SmartCut v0.5.13
スマートレンダリング対応のカットツールです。**カット点にかかる部分 GOP だけを再エンコードし、残りはビット単位でそのままコピーします。**放送録画(MPEG-2 TS)から CM を落とす用途を主眼に置いています。
0.5.13 では、他人の実装と突き合わせて索引の間違いを 2 つ直しました。sorshi/bdav という Python 製の BDAV オーサリングツールが、規格の各欄の値を表にした仕様書を公開しています。別のツールをオラクルにバイト一致まで詰めてあるので、こちらが実ディスクを測って決めた値に対する独立した根拠になります。並べたところ 2 か所食い違い、**両方ともこちらが間違っていました。**カットそのものの動作は変えていません。
ダウンロード
| ファイル | 対象 |
|---|---|
SmartCut_0.5.13_amd64.AppImage |
Linux x64。glibc 2.39 以上(Ubuntu 24.04 / Debian 13 / Fedora 40 以降)。FUSE が必要です |
SmartCut-0.5.13-linux-x86_64.tar.gz |
Linux x64 可搬版。解凍して ./smartcut。中身は AppImage と同じ一式で、FUSE は不要です |
smartcut_0.5.13_amd64.deb |
Debian 13 / Ubuntu 25.04 以降。3.4MB。GUI を smartcut、コマンドライン版を smartcut-cli として入れます |
SmartCut_0.5.13_x64-setup.exe |
Windows x64 インストーラ。WebView2 ランタイムが必要です |
smartcut-portable-x64-0.5.13.zip |
Windows x64 可搬版。解凍して smartcut.exe を実行します |
FFmpeg を別途入れる必要があるのは deb だけです。ほかの配布物には同梱しています。
「ピクチャがどこで終わるか」の段は、等間隔ではありませんでした
エントリーポイントの 3 ビットは、そのエントリーが指しているピクチャがどこまでで終わるかを示します。プレーヤーがピクチャを 1 枚だけ取ってくるために読む欄で、早送りはこれを使います。0.5.12 でここを埋めるようにしたとき、単位はストリーム 128 kB ごとに 1 段だと書きました。これは 3 段目までしか正しくありません。
段の境界は、ソースパケットで 682 / 1364 / 2046 / 3069 / 4774 / 6820 です。最初の 3 つだけが 682 刻み(≒128 kB)で、その上は 4.5 倍・7 倍・10 倍へと伸びます。今回はディスクの索引どうしではなく、ストリームそのものを測り直しました。オーサリングツール製のディスクの m2ts を開き、1019 個のエントリーそれぞれについて「エントリーから次のピクチャの最初のパケットまで」、つまり指しているピクチャが終わる場所を読み出して、ディスクが書いた値と突き合わせています。
| ディスクの値 | 実測したピクチャの長さ | 新しい表 | 0.5.12 の等間隔 |
|---|---|---|---|
| 1 | 487–668 | 1 ✅ | 1 ✅ |
| 2 | 730–1363 | 2 ✅ | 2 ✅ |
| 3 | 1371–2046 | 3 ✅ | 3 ✅ |
| 4 | 2048–3069 | 4 ✅ | 4 が 438 件 / 5 が 73 件 ❌ |
| 5 | 3093–3457 | 5 ✅ | 5 が 7 件 / 6 が 2 件 ❌ |
(単位はソースパケット)
新しい表は 1019 点すべてに一致し、等間隔は 75 点(7.4%)を 1 段高く書きます。外れるのは 393 kB を超えるピクチャで、1080i の放送ではありふれた大きさです。値 3 までは両者が一致するので、0.5.12 の測り方では見えませんでした。索引の値どうしを比べる測り方だったためです。いちばん大きい 2 段だけは手元のどのディスクにも現れないので、そこは sorshi/bdav の表を採っています。
チャプターマークの「どの番組のものか」を、2 バイト手前で読んでいました
レコーダーのディスクのチャプターマークは 46 バイトで、並びは種別・書いたメーカー・所属するプレイアイテム・時刻です。読むほうはプレイアイテムをメーカーの位置で探していました。つまり 3 本しか入っていないディスクに対して「0x212 番目の番組」を要求していたことになります。
これまで表に出ていなかったのは、手元のどのディスクもプレイリスト 1 本につき番組 1 本だからです。その場合は「プレイアイテムを読まない」候補に落ちて結果が合います。出るのは 1 本のプレイリストに複数の番組が入ったディスクで、そのときは番組を特定できる候補がすべて弾かれ、**間違った番組に付ける代わりにマークを捨てていました。**配置は実ディスク 4 枚(レコーダー製 1 枚・オーサリングツール製 3 枚)で確かめてあります。sorshi/bdav が書くのも同じ配置です。
クリップ索引に「どの放送のどの番組か」を書くようにしました
TS_type_info_block は、そのクリップがどのトランスポートストリームのどのサービスから切り出されたかを持つ欄です。手元の実ディスクのうち埋めている 2 枚は、どちらも同じ形で埋めていました。レコーダー製とオーサリングツール製で、16 年離れています。こちらは全部ゼロにして、書いたツールの名前だけ入れていました。放送のテーブルから TSID とサービス ID が取れるときは、同じ形で埋めるようにしました。MP4 から切ったカットのように名乗るテーブルが無いものは、これまでどおり空のままです。
検証
tests/bdav_index.py(プレーヤーの代役として索引の全数値をストリームと突き合わせるもの)に、段がストリームと合うかの検算を足しました。ただしこの検算は合成素材では効きません。フィクスチャのピクチャが小さく、どちらの表でも 1〜3 段にしか入らないためで、実際に旧実装へ戻して通ることを確かめてあります。今回の表を押さえているのは Rust 側のユニットテストのほうです。
ディスク書き出し 67 項目、ディスク読み取り 38 項目、Rust ユニット 188 項目、すべて通過しました。実機での再生は未検証です。おかしなことがあれば issue へお願いします。