13

私はAndroidカメラからローカルUNIXソケットを介してビデオをストリーミングし、ストリームからSDカードにファイルを書き込もうとしています。ファイルがどのプレーヤーでも再生できないことを除いて、すべてが正常に機能します。これは、ソケットがシークできないため、Androidがファイルのギャップを埋めていないためです。私が理解しているように、ビデオストリームが終わった後、私はいくつかの変更を加える必要があります。私はここここここでいくつかの記事を読みましたが、どれも私を助けませんでした。私は手動でそれを行う方法を学ぶために16進エディターで遊んでいるので、後でAndroidコードで同じことをするのは簡単です。

ストリームから保存したサンプルファイルは次のとおりです:https ://dl.dropbox.com/u/17510473/sample_not_playable.3gp

誰かがそれをプレイ可能にして、彼がそれをどのようにしたかを伝えるために修正できますか?

編集:私は3gpファイルのヘッダーを消去し、次のように新しいものを書き込みます:

00 00 00 18 66 74 79 70 33 67 70 34 00 00 03 00 33 67 70 34 33 67 70 36 00 00 00 00

次に、次のコマンドを使用して、mdatおよびmoovアトムの開始位置を見つけます。

grep -aobE "ftyp|mdat|moov" sample_not_playable.3gp

そしてそれは私に次の出力を与えます:

4:ftyp
28:mdat
1414676:moov

次に、1414676 - 28 = 1,414,648 = 0x1595F8

次に、mdatアトムの直前の25〜28バイトとして0x1595F8を書き込みます。したがって、私のヘッダーは次のようになります。

00 00 00 18 66 74 79 70 33 67 70 34 00 00 03 00 33 67 70 34 33 67 70 36 00 15 95 F8

そして、mplayerで再生しようとすると、ビデオとオーディオの出力が破損します。mplayerの出力の一部を次に示します。

[amrwb @ 0x7f72ad652380]Frame too small (33 bytes). Truncated file?
[amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame
[amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame
[amrwb @ 0x7f72ad652380]Frame too small (33 bytes). Truncated file?
[amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame
[amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame
[amrwb @ 0x7f72ad652380]Encountered a bad or corrupted frame
A:  11.0 V:   1.4 A-V:  9.650 ct:  0.023   0/  0 10%  1%  1.6% 0 0                                                        
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f72adeafc40]stream 1, offset 0x15e62b: partial file
[h263 @ 0x7f72ad652380]Bad picture start code
[h263 @ 0x7f72ad652380]header damaged
Error while decoding frame!
[h263 @ 0x7f72ad652380]Bad picture start code
[h263 @ 0x7f72ad652380]header damaged
Error while decoding frame!
[h263 @ 0x7f72ad652380]Bad picture start code
[h263 @ 0x7f72ad652380]header damaged
Error while decoding frame!
A:  11.1 V:   1.5 A-V:  9.558 ct:  0.027   0/  0  9%  1%  1.4% 0 0                                                        
[h263 @ 0x7f72ad652380]Bad picture start code
[h263 @ 0x7f72ad652380]header damaged
Error while decoding frame!

私が間違っていることは何ですか?

4

2 に答える 2

14

理解しておく必要があるのは、mp4 はライブストリーミング可能な形式ではないということです。したがって、とにかくハッキングしてライブストリーミング可能にする方法はありません. 最後にヘッダー[moov atom]を書きます。Android は、フレーム サイズとその他のパラメーターのメモリ内テーブルを作成し、記録の最後にファイルの先頭に書き込みます。このため、ファイル ハンドルのシーク機能が必要です。【ソケットのない方】

暗号化されたコンテンツをディスクに書き込み、誰もファイルを再生できないようにしたい場合は、ファイル全体を暗号化する必要はありません。ヘッダーを暗号化するだけで、ファイル全体を再生できなくなります。

私の以前の段落に納得できないためにファイル全体のエンコーディングがどうしても必要な場合は、ffmpeg のようなものを使用してエンコーディングを行ってください。それを変更すると、暗号化された出力自体が得られ、再びハードディスクに保存されます - ソケット部分が再び削除されます。

Androidでmp4ファイルのライブストリーミングを行う方法はありません。多くの人が無駄に試しているのを見てきましたが、ビデオ/フォーマットを理解していれば、それを行う方法はありません. mp4 はライブ ストリーミング用に設計されていません。フレームサイズを事前に知っていない限り[これは知らない]、正確なエンコーディングの長さは[おそらく知らない] ヘッダーを事前に作成することはできません。

ps。mp4 と 3gp はいとこなので、同じことが当てはまります。

多くの人が、ライブ ストリーミングを http pd や疑似ストリーミングと混同しています。ライブ ストリーミングとは、ファイル全体を持っていないことを意味します。ファイルは作成されており、その場でストリーミングされています。http pd および疑似ストリーミングは、完全に利用可能なファイルで行われます。

編集:

SD カードに保存する前に記録したファイルを暗号化することが目的の場合は、エンコーダーのサポートが必要です。これは、独自のエンコーダーをそこに入れることを意味します。ffmpeg を android にクロスコンパイルします。アプリケーション用の小さな JNI インターフェースを作成します。これを最初に暗号化せずに取得します。完了したら、ffmpeg がストリームを書き込み、暗号化モジュールを追加します。デコード中も同じです。Y3ng作成。これが最もクリーンな方法です。

編集 2: spydroid を参照して、いくつかの機能を取得してください。そこに似たようなものがあります。

編集3:回答の質を向上させるために、他の回答でも与えられた不完全な回避策を説明しています:

生成された mp4 を解析し、エレメンタリ ストリームをソケット経由で個別に送信することで、AV をストリーミングすることもできます。直面する唯一の問題は、AV サンプルの正確なタイムスタンプがわからないため、完全な AV 同期が得られないことです。Android だけがそれを知っており、最後に mp4 ヘッダーに書き込みます。だから、あなたには良くありません。ビデオ フレームの完全なサンプリング レートを想定する必要があり、オーディオは 20ms パケットを想定するために amr である必要があります。他のオーディオのケースでは、ロングランでドリフトが見られるようになります [特に動きの激しいシーンが始まる場合]。これは、生成された各オーディオ パケットが一定の継続時間に対応していないためです [amr およびその他の音声コーデックを除く]。

于 2012-08-28T20:31:23.560 に答える
4

まず第一に、あなたがやろうとしていることはあまり明確ではありません。

ビデオをプログラムで再生可能なファイルに保存したいだけですか? その場合は、UNIX ソケットの代わりにファイル記述子を使用するだけです。MediaRecord のこの API は、ランダム アクセスという理由から、(UNIX ソケットではなく) ファイルで動作するように設計されています。したがって、私の最初のアドバイスは、ファイル記述子を使用することです。これにより、記録の最後に正しいファイルが得られます。

ここで例を取得できます: Android でビデオ録画をキャプチャするにはどうすればよいですか?

この場合、デバイスからビデオをストリーミングするアプリケーションを作成しようとしている場合は、ストリームをリアルタイムで解析し、フレームごとに分割し、フレームを個別に送信する必要があります。そして、最も複雑な部分はストリームの解析です (特にデータがオーディオとインターリーブされている場合、H263 などの一部のビデオ コーデックは解析できますが、他のコーデックは解析できません)。

これらの 2 つのプロジェクトのいずれかがそのような機能を実装していると思います: http://sipdroid.org/ http://code.google.com/p/imsdroid/

于 2012-08-23T18:55:07.350 に答える