OpenCV와 GStreamer를 사용하여 RTSP Streaming을 C++ 코드로 만들어보고 간단히 테스트도 진행해봅니다.
2023. 12. 26 최초작성
2024. 1. 14 추가로 필요한 패키지
0. 다음 포스트를 참고하여 Ubuntu에 OpenCV를 설치합니다.
Ubuntu 22.04에 CUDA 사용하는 OpenCV 설치하는 방법
https://webnautes.tistory.com/1876
추가로 필요한 패키지를 다음 포스트를 보고 설치해야 합니다. 패키지 설치후, 테스트 삼아 진행해보는 것도 좋을 듯합니다.
Ubuntu에 GStreamer 설치하고 웹캠 영상 가져와보기
https://webnautes.tistory.com/2067
1. 추가로 필요한 패키지를 설치합니다.
$ sudo apt install gstreamer1.0-rtsp
2. 아래 링크에서 linux amd64용의 링크를 복사하여 다음처럼 다운로드 받아 미리 터미널에서 실행시켜 둬야 합니다. 글작성 시점에서 최신 버전은 1.4.1입니다.
https://github.com/bluenviron/mediamtx/releases
$ wget https://github.com/bluenviron/mediamtx/releases/download/v1.4.1/mediamtx_v1.4.1_linux_amd64.tar.gz
$ tar xvzf mediamtx_v1.4.1_linux_amd64.tar.gz
$ ./mediamtx
실행시키면 다음과 같은 로그가 출력됩니다.
webnautes@webnautes-laptop:~$ ./mediamtx
2023/12/26 17:50:11 INF MediaMTX v1.4.1
2023/12/26 17:50:11 INF configuration loaded from /home/webnautes/mediamtx.yml
2023/12/26 17:50:11 INF [RTSP] listener opened on :8554 (TCP), :8000 (UDP/RTP), :8001 (UDP/RTCP)
2023/12/26 17:50:11 INF [RTMP] listener opened on :1935
2023/12/26 17:50:11 INF [HLS] listener opened on :8888
2023/12/26 17:50:11 INF [WebRTC] listener opened on :8889 (HTTP), :8189 (ICE/UDP)
2023/12/26 17:50:11 INF [SRT] listener opened on :8890 (UDP)
3. 다음 OpenCV 코드를 컴파일 후 새로운 터미널에서 실행합니다. GStreamer와 OpenCV를 사용하여 웹캠에서 영상을 받아서 RTSP 스트리밍하는 코드입니다.
$ g++ opencv_gst.cpp -o opencv_gst `pkg-config --cflags --libs opencv4`
$ ./opencv_gst
#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { cv::VideoCapture cap("v4l2src device=/dev/video0 ! videoconvert ! video/x-raw, framerate=30/1, width=640, height=480, format=BGR ! appsink", cv::CAP_GSTREAMER); if (!cap.isOpened()) { cout << "can't create video capture\n"; return -1; } cv::VideoWriter writer; writer.open("appsrc ! videoconvert ! x264enc tune=zerolatency ! rtspclientsink location=rtsp://127.0.0.1:8554/my", cv::CAP_GSTREAMER, 0, (double)30, cv::Size(640, 480), true); if (!writer.isOpened()) { cout << "can't create video writer\n"; return -1; } cv::Mat frame; int key; while (true) { cap >> frame; if (frame.empty()) break; cv::putText( frame, "test", Point(10,40), 2, 1.2, Scalar(0, 255, 0) ); cv::imshow("image", frame); writer.write(frame); key = cv::waitKey( 30 ); if (key==27) break; } } |
앞에서 mediamtx 실행해둔 창에 다음 로그가 출력됩니다.
2023/12/26 17:51:03 INF [RTSP] [conn 127.0.0.1:56308] opened
2023/12/26 17:51:03 INF [RTSP] [session 3178404c] created by 127.0.0.1:56308
2023/12/26 17:51:04 INF [RTSP] [session 3178404c] is publishing to path 'my', 1 track (H264)
4. 다음처럼 실행하여 스트리밍된 영상을 받아서 재생하는 테스트해봅니다. OpenCV로 작성한 코드로도 테스트 해볼 수 있습니다.
$ gst-play-1.0 rtsp://localhost:8554/my
다음 에러가 발생할수 있습니다.
$ gst-play-1.0 rtsp://localhost:8554/my
Press 'k' to see a list of keyboard shortcuts.
Now playing rtsp://localhost:8554/mystream
Pipeline is live.
ERROR 자원에서 설정을 읽거나 쓸 수 없음. for rtsp://localhost:8554/mystream
ERROR debug information: ../gst/udp/gstmultiudpsink.c(1228): gst_multiudpsink_configure_client (): /GstPlayBin:playbin/GstURIDecodeBin:uridecodebin0/GstRTSPSrc:source/GstUDPSink:udpsink0:
Invalid address family (got 10)
Reached end of play list.
(gst-play-1.0:31909): GStreamer-CRITICAL **: 17:42:09.705:
Trying to dispose element playbin, but it is in PAUSED instead of the NULL state.
You need to explicitly set elements to the NULL state before
dropping the final reference, to allow them to clean up.
This problem may also be caused by a refcounting bug in the
application or some element.
구글링해보니 문제가 되는 부분은 로그에서 Invalid address family (got 10) 부분이라서 ip v6를 비활성화 해봤습니다. 왜냐하면 got 10이 ip v6를 의미한다네요.
/etc/sysctl.conf 파일을 열어서 마지막줄에 다음 한줄을 추가합니다.
net.ipv6.conf.all.disable_ipv6 = 1
그리고나서 다음 명령을 실행하면 적용이 됩니다.
sudo sysctl -p
다시 실행해봅니다.
$ gst-play-1.0 rtsp://localhost:8554/my
Press 'k' to see a list of keyboard shortcuts.
Now playing rtsp://localhost:8554/my
Pipeline is live.
Redistribute latency...
Redistribute latency...
Redistribute latency...
Redistribute latency...
Redistribute latency...
Redistribute latency...
Redistribute latency...
웹캠 영상이 보입니다. 딜레이가 약간 있는 상태가 되는데 이건 OpenCV에 있는 두번째 GStreamer 파이프라인의 옵션을 변경해서 해결해야 합니다. 추가해야 하는 옵션은 네트워크 환경과 웹캠 해상도에 따라 달라질 수 있습니다.
참고
https://github.com/aler9/rtsp-simple-server/issues/20
https://stackoverflow.com/questions/37339184/how-to-write-opencv-mat-to-gstreamer-pipeline
https://qiita.com/k-yamada-github/items/1deaa6e81081e4a1aa35
'Gstreamer' 카테고리의 다른 글
Ubuntu에 GStreamer 설치하고 웹캠 영상 가져와보기 (0) | 2023.10.18 |
---|---|
GStreamer를 RTSP Client로 사용시 패스워드에 @가 포함되어 있다면 인증 에러가 발생합니다. (0) | 2023.10.14 |
Visual Studo 2019에서 GStreamer 사용하기 (0) | 2023.10.14 |
Visual Studio 프로젝트의 코드에서 Gstreamer 플러그인 위치 지정 (0) | 2023.10.13 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!