Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RTSPクライアントを自作してみた話
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
simotin13
May 30, 2026
Programming
660
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RTSPクライアントを自作してみた話
simotin13
May 30, 2026
More Decks by simotin13
See All by simotin13
C/C++用のコードカバレッジツールを自作してみた話
simotin13
0
52
マイコン向けのただのリンカを自作してみた話
simotin13
0
110
Pinでコードカバレッジツールを自作してみた話
simotin13
0
1.8k
Other Decks in Programming
See All in Programming
信頼性について考えてみる(SRE NEXT 2026 miniLT)
hayama17
0
210
AIキャラアプリkaiwaの低遅延音声通話基盤をどう作ったか - AWS Gravitonで支える低遅延・低コストAI Agent基盤
mogamit
0
190
吝嗇家のためのAI活用 / AI development for miser - ChatGPT + Issue Driven Development
tooppoo
0
200
PHP に部分適用が来るぞ!……ところで何それ?おいしいの? #phpcon / phpcon-2026
shogogg
0
370
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
280
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
170
コーディングルールの鮮度を保ちたい for SRE NEXT 2026 / keep-fresh-go-internal-conventions-sre-next-2026
handlename
0
150
Laravel Boostに学ぶ、AIにPHPを書かせる技術 〜OSSの実装から蒸留するエージェント制御の王道〜
kentaroutakeda
3
530
言語を使う側から、作る側へ。 自作 Lisp で得た新たな気づき。
andpad
0
130
人間の目はかわらない、だからJPEGは30年もつ
yuzneri
9
15k
霧の中の代数的エフェクト
funnyycat
1
430
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
410
Featured
See All Featured
Ten Tips & Tricks for a 🌱 transition
stuffmc
0
160
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
270
What’s in a name? Adding method to the madness
productmarketing
PRO
24
4.1k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
280
Building Applications with DynamoDB
mza
96
7.1k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
3
360
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.1k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.5k
Building the Perfect Custom Keyboard
takai
2
820
Transcript
RTSPクライアントを自作してみた話 @simotin13
Who am I? @simotin13 Hiroyuki Miyazaki ・関西で主に組込系のコード書いてます。 ・低レイヤなネタとかが好きです。
Overview ・動画ストリーミング用プロトコルRTSPのクライアントを自作してみました。 (Rust) ・RTSPカメラの映像の録画(.mp4)と再生(GUI表示)ができます。 ・映像(H.264)のみ音声は未対応、認証とか細かいところは未実装な点が あります。 ▪Github https://github.com/simotin13/rtsp-client
Overview~RTSPとは何か~ Real Time Streaming Protocol。 ネットワークカメラ、ライブ配信などで使われるプロトコル Real Time Streaming Protocol
市販のRTSP対応ネットワークカメラ (Tp-Linkとか) RTSP対応ソフト (VLC media playerとか) RTSPでストリーミングを受信して録画がしたい。
Q1.FFmpegでよいのでは?
Q1.FFmpegでいいのでは? ・ffmpegコマンドではエラーハンドリング(通信異常とか)ができない。 →stdout,stderrだけでは苦しい。録画には向かない?
Q2.GStreamerでよいのでは?
Q2.Gstreamerでいいのでは? ・ライブラリとして利用しやすい →自分でエラーハンドリングを実装できる ・エラーハンドラを実装していてもハンドリングできないことがあ る(ときどき起きた)
Q2.Gstreamerでいいのでは? エラーハンドラを実装していてもハンドリングできないことがある ・カメラの映像録画でエラーハンドリングができないと録画時間分のデータが 無駄になる(30分の録画の場合29分59秒でエラーが起きたら…) ・Gstreamerのログレベルを下げて、解析しようとするとログが大量に出力さ れる(数百MB~数GB)ため、解析が簡単にできない。
エラーハンドリングはどうすべき? Gstreamerでエラーハンドリン グが出来なくて録画が失敗 するとき、どう実装をすれば いいかわからないの… 経験豊富な先輩に聞いてみる。
エラーハンドリングはどうすべき? A. カメラとの相性とかあるし、GStreamerあ るあるですね。 使うカメラが固定でmp4に落とすだけ なら自作した方が早いと思うよ。 経験豊富な先輩からの回答。
RTSPクライアントを自作する ▪作り方 1.RTSPでストリーミングを開始する 2.ストリーミング(RTP)パケットから映像(H.264)を取り出す 3.取り出した映像を.mp4ファイルに保存する Real Time Streaming Protocol
RTSPクライアントを自作する RTSPでストリーミングを開始する。 RTSPはほとんどHTTPと同じ。 ・リクエストライン、リクエストヘッダ、リクエストbody ・ステータスライン、レスポンスヘッダ、レスポンスbody RTSP自体ではストリーミングデータをやり取りしない。 ストリーミングを含むRTP/RTCPを制御する。 # リクエスト DESCRIBE
rtsp://192.168.1.10/stream RTSP/1.0 CSeq: 2 Accept: application/sdp # レスポンス RTSP/1.0 200 OK CSeq: 2 Content-Type: application/sdp Content-Length: 120 v=0 o=- 0 0 IN IP4 127.0.0.1
ストリーミングの始め方 SETUP Transport: RTP/AVP;unicast;client_port=5000-5001 RTP,RTCPを受信するポート番号を指定する。 OPTIONS DESCRIBE PLAY サポートしているメソッドの一覧を返す。 OPTIONS自体送らなくても動くけど、一応最初に送るのが作法らしい。
ストリームの内容をSDP(Session Description Protocol)で返す。★これ重要! RTSP/1.0 200 OK RTSP/1.0 200 OK
ストリーミングの始め方 ・DESCRIBEのレスポンスでトラック毎(映像・音声)の情報が得られる。 →SETUPコマンドを呼び出す際に利用する。 ・SETUPコマンドで受信したいトラックのストリーミング方法を要求する。 →UDP?TCP?ポート番号 ・SETUPのあと、PLAYメソッドを呼び出すとRTPでストリーミングが始まる。
RTPでのストリーミングデータの受信 ▪RTPのデータフォーマット RTPヘッダ:12byteとデータ部で構成される ▪RTPヘッダの内容 RTP Header(12 byte) Payload(n byte) 内容
サイズ フィールド バージョン(2固定) 2bit Version パディング有無 通常は0 1bit Padding header extension 有無 1bit Extensition audio mixer 用 通常は0 4bit CSRC Count コーディック依存 H.264ではframe終了を表す 1bit Marker ペイロードタイプ 7bit Payload Type シーケンス番号 16bit Seq Frameのタイムスタンプ 32bit Timestamp ストリームID(送信元ID) 32bit SSRC
NAL(Network Abstruct Layer)の解析 RTPのpayload_typeやSSRCをもとに映像データかどうかが判断できる H.264の場合、RTPのデータ部にNAL(Network Abstruct Layer)というデータ構 造でデータが格納されている。 NAL Header(1
byte) Payload(n byte) 内容 サイズ フィールド forbidden_zero_bit(0固定) 1bit F フレーム間予測での参照値 2bit nal_ref_idc フレームタイプ 5bit Type
NAL(Network Abstruct Layer)の解析 NALのデータによっては、複数のRTPパケットに分割されて送信されたり、1回のRTPのデー タの中に複数のNALユニットが含まれている場合がある。 映像を正しく表示・録画するためには、SPS・PPS の受信して保持しておく必要がある。 SPS(Sequence Parameter Set):映像の設定値(width,height,
H.264のprofile) PPS(Picture Parameter Set): H.264のデコード用情報 内容 NALタイプ(番号) 複数のRTPパケットに分割して1つのNAL(基本的には画像フレームの データ)を送信する。 フレームデータは基本的にこのNALタイプで飛んでくることが多い。 FU-A(28) 1つのRTPパケットに複数のNALユニットが含まれている。 SPSやPPSはフレームデータと比べてデータ長が小さいので1つのRTP パケットにまとめることができる。 STAP-A(24) 1つのRTPパケットに複数の画像フレームデータをまとめる。 実際には1フレームは大きいので使われてないっぽい。 STAP-B(25)
NAL(Network Abstruct Layer)の解析 NALからフレームデータを取り出してh264のデコードすることで受信した映像 をjpegなどの画像として保存できるので正しく実装できているか確認できる。 受信と解析が適切にできていないとよくわからない画像が表示される。
MP4への書き込み~boxデータ構造~ 受信したNALからSPSやPPS、映像フレームデータを 取り出せたらMP4のファイルに書き込んでいく。 MP4はbox(Atom)と呼ばれるデータのかたまりの集合。 boxの仕様はISO/IEC 14496-12で決められている。 boxの中にboxを入れ子に含むことができる。 タイプ毎にいろんなデータがboxに含まれている。 ftyp mdat
moov mvhd Trak mdia size(4 byte) type(4 byte) data(n byte) … … 内容 Boxタイプ ファイルの概要 ftyp 映像・音声データ(H.264,AVC…etc) mdat 動画のメタデータ moov
MP4への書き込み~boxデータ構造~ Boxの種類(ftyp,mdat…etc)は分かるけど、具体的にどのboxに どういうフォーマットで書き込んでよいのかはわからない。
NALの受信と解析まで実装できました。 .mp4ファイルに保存して録画できるようにしたい。 Sonet4.6 ▽ MP4への書き込み~AIに相談してみる~ こういうときはやはりAI!.mp4の具体的な書き方を教えてくれるはず。
ffmpegにH.264ストリームをパイプする のが最も確実な方法です。 MP4への書き込み~AIに相談してみる~ 何の解決にもならない答えが返ってくる
MP4への書き込み~FFmpegを参考にする~ AIに聞いてもわからないのでFFmpegの該当する実装を探してみる。 libavformatのmovenc.cでmp4への書き込み処理が実装されている。 これを踏まえて再度AIに相談してコードを生成してもらうことで.mp4に保存で きた。
MP4への書き込み~FFmpegを参考にする~ ・トップレベルには ftyp:mp4ファイルの概要 mdat:フレーム毎のデータ長とデータの繰り返し moov:メタデータの集合 mdatは録画中に追記していけるが、moovのメタデータ は基本的に録画終了時にしか書けない。 書き方にもmoovを先頭に書く方式や末尾に書く方式 がありメリット・デメリットがある。
おまけ~Playerも作ってみる~ 録画ができたのでついでにリアルタイムにストリーミングを表示できるplayer も作ってみたくなる。(起動時のオプションでplayerとして起動) Rustではeguiを使うとクロスプラットフォームのGUIが作れて便利 →Windows,Ubuntuで動いた。
まとめ ・Rustで2000行未満で書けるので、「RTSPクライアント自作した方が早い説」は 規模間的には正しそう。 ただし、あくまでサブセットなので、使用するカメラやシステム構成が決まって いることが前提。あとMP4の仕様についても知識があることが前提。
ご清聴どうもありがとうございました。