2025/03/14更新
2022年6月に作成した記事を、Windows 11 + Ubuntu 24.04 LTSの環境を念頭に更新しました。
前回はWindowsからWSL2へFFMPEGでUSBカメラの映像をストリーミングすることで、WSL2上のOpenCVでUSBカメラの映像を取得してみました。
このときはWindowsからUSBカメラの映像をストリーミングする際にFFMPEGというソフトを使いましたが、今回はVLC media playerを使ってみたいと思います。
WSL2でUSBカメラを利用するためのストリーミング
WSL2は仮想環境のようなものでUSBデバイスを直接利用できません。
WSL2でUSBカメラを使うためにはUSBをIPに変換する方法があります。


しかし、これにはいくつか課題があり、代替案としてネットワークストリーミングを利用したのが前回の記事です。

この記事では、WindowsからUSBカメラの映像をストリーミングするためには、FFMPEGというツールを利用しました。
このFFMPEGは大変多機能なのですが、コマンドラインで操作しなければならず、少々とっつきにくいところがあります。
そこで今回はGUIで操作できるVLC media playerを利用したいと思います。
構築するシステムは
- USBカメラはWindows PCに接続する
- Windows PCからWSL2のLinuxへUSBカメラの映像をストリーミングする
- WSL2のLinuxで動作するOpenCVではストリーミングされた映像を受信する
という形になります。
今回はこの2番目のステップでVLC media playerを利用します。
Windows側の準備
Windowsにはストリーミングを行うソフトウェアとしてVLC media playerをインストールします。
VLC media playerは下記のサイトからダウンロードできます。
最近ではMicrosoft Storeからも入手できるようです。
インストール自体は簡単なので説明する必要はないと思います。
WSL2側の準備
WSL2のLinuxで導入する必要があるのはOpenCVとFFMPEGです。FFMPEGは事前の動作確認時に利用します。
OpenCVについては次のコマンドで導入できます。
sudo apt-get install libopencv-dev
FFMPEGのインストールは次のコマンドです。
sudo apt-get install ffmpeg
またストリーミングに必要な情報としてWSL2側のIPアドレスが必要です。WSL2のIPアドレスは次のコマンドで表示されます。
$ hostname -I
172.21.92.66
つまりWSL2側のIPアドレスは「172.21.92.66」となります。このIPアドレスはのちのち使うのでメモしておきます。
VLCによるUSBカメラのストリーミング
それではWindowsにインストールしたVLC media playerを使ってUSBカメラの映像をストリーミングしてみましょう。
ストリーミングの開始
VLC media playerを起動したら、メニューで「メディア」→「キャプチャーデバイスを開く」を選択します。
「メディアを開く」というウィンドウが開いたら、「デバイスの選択」の「ビデオデバイス名」の欄から接続しているUSBカメラの名前を選びます。
続いて右下の「再生ボタン」の右側の「▼」を選択し、表示された選択肢の中から「ストリーム再生」を選択します。
続いて「ストリーム出力」というウィンドウが表示されます。
最初の「入力元」についてはそのまま「次へ」を選択してOKです。
続いて出力先の設定です。
ここでは新しい出力先として「UDP (legacy)」を選択して「追加」を選択します。
ここで「ローカルで再生する」をチェックしておくと、ストリーミング中の映像を見ることができます。
新しい出力先としてUDPを追加すると、次のような画面になります。
ここでは「アドレス」に先ほど調べたWSL2のLinuxのIPアドレスを入力します。ポート番号は何でも良いのですがここでは「1234」としておきます。
続いてトランスコーディングの設定です。
ここでは「トランスコーディングを有効にする」をチェックした上で、プロファイルとして「Video – H.264 + MP3 (TS)」を選択します。
ここでプロファイルの右側のスパナアイコンを選択すると、ビットレートなどのカスタマイズができますが、今回は説明を省略します。
最後に「すべての基本ストリームをストリーミングする」をチェックして右下の「ストリーム」を選択します。
これでVLC media playerによるストリーミングが開始されます。
VLC media playerの画面には「Converting ddshow://」と表示されます。
このとき左下のタイムコードが時間とともに増加していけば、ストリーミングが正常に開始しています。
ストリーミングの確認
VLC media playerによるストリーミングを開始したら、このストリーミングデータがWSL2側に届いているかどうかを確認してみましょう。
この確認はFFMPEGに付属する「ffplay」というコマンドを利用します。WSL2側のターミナルで
ffplay udp://@:1234
を実行してみましょう。
最初は
[h264 @ 0x7fcfa8029540] decode_slice_header error
[h264 @ 0x7fcfa8029540] no frame!
[h264 @ 0x7fcfa8029540] non-existing PPS 0 referenced
Last message repeated 1 times
[h264 @ 0x7fcfa8029540] decode_slice_header error
[h264 @ 0x7fcfa8029540] no frame!
[h264 @ 0x7fcfa8029540] non-existing PPS 0 referenced
Last message repeated 1 times
[h264 @ 0x7fcfa8029540] decode_slice_header error
[h264 @ 0x7fcfa8029540] no frame!
[h264 @ 0x7fcfa8029540] non-existing PPS 0 referenced
Last message repeated 1 times
[h264 @ 0x7fcfa8029540] decode_slice_header error
[h264 @ 0x7fcfa8029540] no frame!
とエラーっぽいメッセージが表示されますが、5~10秒ほど待つとウィンドウが表示され、USBカメラの映像(=WindowsのVLC media playerでストリーミングされている映像)が表示されるはずです。
これでVLC media playerでストリーミングができることが確認できました。
WSL2のターミナルでffplayコマンドを実行する際には、WSL2でGUIが利用できる状態で行ってください。

WSL2上のOpenCVによるキャプチャ
前回のFFMPEGを使ったストリーミングでは、H.264でストリーミングするとOpenCVで受信できなかったため、Motion JPEGを利用しました。
しかし、ストリーミングをVLC Playerで行う場合は、H.264でも問題なくOpenCVで受信できるようです。
ようやく本題です。
WSL上のOpenCVで上記のVLC media playerによるストリーミングをキャプチャするために、次のようなソースコードを作成します。
#include <string>
#include <iostream>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
int main(int argc, char* argv[]) {
const std::string window_name("OpenCV Sample");
cv::VideoCapture cap("udp://@:1234", cv::CAP_FFMPEG);
if ( !cap.isOpened() ) {
std::cerr << "Can't open capture device" << std::endl;
return -1;
}
cv::namedWindow(window_name, cv::WINDOW_GUI_NORMAL | cv::WINDOW_AUTOSIZE);
cv::Mat frame;
while (1) {
cap >> frame;
if ( frame.empty() ) {
std::cerr << "Fail to capture video" << std::endl;
continue;
}
cv::imshow(window_name, frame);
if ( cv::waitKey(1) >= 0 ) {
break;
}
}
return 0;
}
このファイルをcapture-streaming.cppとして保存して、次のようにコンパイルします。
/usr/bin/g++ -I/usr/include/opencv4 -fdiagnostics-color=always capture-streaming.cpp -o capture-streaming -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_videoio
ビルドに成功すると「capture-streaming」というファイル名の実行ファイルが生成されます。
そしてその実行ファイルを実行してみます。
./capture-streaming
5秒ほどすると「OpenCV Sample」というタイトルのウィンドウが表示され、そのウィンドウでUSBカメラの映像(=Windows上のVLC media playerがストリーミングしている映像)が表示されます。
もし「Can’t open capture device」というエラーになってしまう場合は
- Windows上のVLC media playerでストリーミングを開始しているか?
- 他にストリーミングを受信しているプログラムはないか?(たとえば、テストに利用したffplay)
を確認してみてください。
まとめ
今回はWSL2上のOpenCVでUSBカメラの映像を取得するために、Windows上のVLC media playerを使ってストリーミングしてみました。
VLC media playerを利用することで、GUIでストリーミングの設定をすることができるのでFFMPEGよりも簡単かもしれません。
遅延が大きいなどの制限はありますが、WSL2上のOpenCVでUSBカメラの映像を取得したい方は、ストリーミングを試してみてください。
次回はWordPressの執筆環境を考えたいと思います。
コメント