---
# System prepended metadata

title: How to display video in docker container 如何在docker容器中播放影片
tags: [video, container, real-time, stream, docker]

---

# How to display video in docker container 如何在docker容器中播放影片
###### tags:`docker` `video` `real-time` `container` `stream` 

## NVIDIA Jetson 平台佈署相關筆記
### 基本環境設定
- [Jetson AGX Xavier 系統環境設定1_在windows10環境連接與安裝](https://hackmd.io/@YungHuiHsu/HJ2lcU4Rj)
- [Jetson AGX Xavier 系統環境設定2_Docker安裝或從源程式碼編譯](https://hackmd.io/k-lnDTxVQDWo_V13WEnfOg)
 - [NVIDIA Container Toolkit 安裝筆記](https://hackmd.io/wADvyemZRDOeEduJXA9X7g)
- [Jetson 邊緣裝置查詢系統性能指令jtop](https://hackmd.io/VXXV3T5GRIKi6ap8SkR-tg)
- [Jetson Network Setup 網路設定](https://hackmd.io/WiqAB7pLSpm2863N2ISGXQ)
- [OpenCV turns on cuda acceleration in Nvidia Jetson platform<br>OpenCV在Nvidia Jetson平台開啟cuda加速](https://hackmd.io/6IloyiWMQ_qbIpIE_c_1GA)

### 模型佈署與加速
- [[Object Detection_YOLO] YOLOv7 論文筆記](https://hackmd.io/xhLeIsoSToW0jL61QRWDcQ)
- [Deploy YOLOv7 on Nvidia Jetson](https://hackmd.io/kZftj6AgQmWJsbXsswIwEQ)
- [Convert PyTorch model to TensorRT for 3-8x speedup<br>將PyTorch模型轉換為TensorRT，實現3-8倍加速](https://hackmd.io/_oaJhYNqTvyL_h01X1Fdmw?both)
- [Accelerate multi-streaming cameras with DeepStream and deploy custom (YOLO) models<br>使用DeepStream加速多串流攝影機並佈署客製(YOLO)模型](https://hackmd.io/@YungHuiHsu/rJKx-tv4h)
- [Model Quantization Note 模型量化筆記](https://hackmd.io/riYLcrp1RuKHpVI22oEAXA)

---

## 問題

### 情境描述:
在container環境(dustynv/jetson-inference:r35.2.1)執行.py檔時，調用opencv時報錯：

### 錯誤訊息:
> "cv2.imshow(str(p), im0)
> cv2.error: OpenCV(4.5.0) /opt/opencv/modules/highgui/src/window_gtk.cpp:624: error: (-2:Unspecified error) Can't initialize GTK backend in function 'cvInitSystem'"

### 可能原因:
#### docker容器內沒有安裝顯示設定

## 解決方案
### 方案1：讓container共用host主機的顯示設定
要在Docker容器中實時顯示視頻，可以使用Docker的X11轉發功能(X11 forwarding feature)，將X11顯示從容器轉發到主機系統，然後在主機系統上使用影片撥放器(GStreamer,VLC Player)或video streaming protocol如RTSP或WebRTC)來顯示影片。
 

1. 在啟用container時需要先設置好如何共用host的顯示設定
    啟用前先執行以下指令(每次重開機時)
    ```
    sudo xhost +si:localuser:root
    ```
    - 這條命令是用來允許當前使用者授權給容器中的root使用者，使用host機上的X伺服器。 
        - `xhost`命令用於控制X伺服器的訪問控制
        - `+si：localuser：root`表示授權給容器中的root使用者使用宿主機上的X伺服器
        - ``+si`選項的作用是啟用了“安全介面”（secure mode）並且允許本地的普通使用者（即非root使用者）以root身份訪問X伺服器。
            
    X伺服器通常會將X顯示器設備（如顯示器或VNC會話）作為未經身份驗證的網路端點公開，這可能會造成安全風險。 啟用安全介面可以限制哪些客戶端能夠連接到X伺服器，並允許用戶端身份驗證。 在這個命令中，+si選項告訴X伺服器只允許本地用戶連接，並使用“安全資訊（secure information）”進行身份驗證。

    當使用Docker等容器技術時，啟用安全介面並允許非root使用者以root身份訪問X伺服器，可以讓容器內的應用程式使用圖形介面，並且限制對主機的訪問許可權。
    
2. 在啟用container時，傳入以下變數

    ```
    docker run -it \
        --env="DISPLAY=$DISPLAY" \
        --volume="/tmp/.X11-unix:/tmp/.X11-unix" \
        YOUR_IMAGE
    ```


    - `--env=“DISPLAY=$DISPLAY”`：
        - 設置容器中的 DISPLAY 環境變數，將其值設置為與宿主機相同的值。 
        - 這個環境變數用於指定 X11 顯示伺服器的位址和埠號，以便容器中的應用程式能夠將圖形介面輸出到主機上


    - `--volume="/tmp/. X11-unix:/tmp/. X11-unix：rw“`：
        - 將主機中的 /tmp/. X11-unix 目錄掛載到容器中的 /tmp/. X11-unix 目錄，以便容器中的應用程式能夠訪問主機上的 X11 顯示伺服器

    - `DISPLAY`環境變數
        - 它是一個由 X Window System 使用的環境變數，用於指定 X11 顯示伺服器的位址和埠號。 
        - 在 Linux 系統上，X11 顯示伺服器通常運行在 ：0 的埠上，因此 DISPLAY 的預設值是 ：0。 在上面的命令中，`DISPLAY=$DISPLAY` 將容器中的 `DISPLAY` 環境變數設置為與宿主機相同的值，以便容器中的應用程式能夠將圖形介面輸出到主機上。 
        - 通過將主機上的 ``/tmp/. X11-unix`` 目錄掛載到容器中的 /tmp/. X11-unix` 目錄，容器中的應用程式能夠通過 X11 顯示伺服器連接到主機上的顯示設備。

- X11
:::info
X11（也稱為X Window System或簡稱為X）是一種在Unix、Linux和類Unix系統上運行的圖形使用者介面（GUI）系統。 它提供了一種跨網路顯示和交互的方法，使得在本地電腦上運行的應用程式可以顯示在遠端計算機上，並且可以通過網路進行控制和輸入。 X11系統通常由X伺服器和X客戶端組成。 X伺服器是一個運行在遠端電腦上的程式，它控制圖形顯示設備並接受來自X用戶端的請求。 X用戶端是執行在本地電腦上的程式，它將圖形介面渲染為X協定，並將其發送到X伺服器進行顯示。 X11是一個開放標準，具有廣泛的應用，被許多Unix和類Unix操作系統所採用。
![](https://i.imgur.com/9xMYTJ6.png)

:::
