Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
RTSPクライアントを自作してみた話
Search
simotin13
May 30, 2026
Programming
750
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
62
マイコン向けのただのリンカを自作してみた話
simotin13
0
140
Pinでコードカバレッジツールを自作してみた話
simotin13
0
1.9k
Other Decks in Programming
See All in Programming
R8 の設定見直しでアプリサイズ削減
andpad
0
220
Unity6 URPによる海底をテーマにしたVJシステムの解説 | Unity Shader 完全に理解した 勉強会
gam0022
0
370
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
220
見えないものを探る要求要件定義に必要な基本的思考 / invisible-requirement-thinking
minodriven
15
8.5k
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
220
Next.js: The final boss of Web Performance
guaca
0
260
コードレビューのボトルネックを"する側"と"される側"の両面から解消する
yub0n
2
1.6k
ソニーのクラウド共通基盤の変遷とAI時代の開発スタイルに合わせた進化 / The Journey of Sony’s Common Cloud Platform and Its Evolution for AI-Native Development
kenjiyoneyama
0
270
Agents on Rails - Rails at Scale 2026
irinanazarova
0
560
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
380
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
160
自サークルのIdPからログアウトできるようになるまで
taiseiue
1
140
Featured
See All Featured
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
410
Context Engineering - Making Every Token Count
addyosmani
9
1.2k
Imperfection Machines: The Place of Print at Facebook
scottboms
270
14k
A designer walks into a library…
pauljervisheath
211
25k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
890
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
Pawsitive SEO: Lessons from My Dog (and Many Mistakes) on Thriving as a Consultant in the Age of AI
davidcarrasco
0
260
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.2k
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.5k
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
220
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
630
How Software Deployment tools have changed in the past 20 years
geshan
2
35k
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の仕様についても知識があることが前提。
ご清聴どうもありがとうございました。