6

ローカル ソケットを介して Android の MediaRecorder から h264/AAC ビデオを送信しようとしています。目標は、RTMP または RTSP を介して WOWZA サーバーにビデオを送信することですが、多くの問題が発生しており、今のところ LocalServerSocket からファイルにデータを書き込もうとしています。

ここにいくつかのコードがあります。申し訳ありませんが、あまりきれいではありませんが、私は多くのことをテストするのに何時間も費やしました。私のプロジェクトは今混乱しています。

カメラ アクティビティでは、出力ファイルの設定:

LocalSocket outSocket = new LocalSocket();

try {
    outSocket.connect(new LocalSocketAddress(LOCAL_SOCKET));
} catch (Exception e) {
    Log.i(LOG_TAG, "Error connecting socket: "+e);
}
mMediaRecorder.setOutputFile(outSocket.getFileDescriptor());

LocalServerSocket の実装:

try {
    mLocalServerSocket = new LocalServerSocket(mName);
} catch (Exception e) {
    Log.e(LOG_TAG, "Error creating server socket: "+e);
    return;
}

while (true) {

    File out = null;
    FileOutputStream fop = null;
    try {
        mLocalClientSocket = mLocalServerSocket.accept();

        InputStream in = mLocalClientSocket.getInputStream();

        out = new File(mContext.getExternalFilesDir(null), "testfile.mp4");
        fop = new FileOutputStream(out);

        int len = 0;
        byte[] buffer = new byte[1024];
        while ((len = in.read(buffer)) >= 0) {

            Log.i(LOG_TAG, "Writing "+len+" bytes");
            fop.write(buffer, 0, len);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    finally{
        try {
            fop.close();
            mLocalClientSocket.close();
        } catch (Exception e2) {}
    }
}

問題は、これによって作成されたファイルがどのメディア プレーヤーでも読み取れないことです。これはエンコーディングの問題によるものだと思いますか? よく理解すれば、このコードはバイナリ ファイルを生成するはずですか?!

よろしくお願いします。

4

3 に答える 3

2

ファイルを再生できない理由がわかりました。MP4 および 3GPP ファイルには、次のバイトを含むヘッダーがあります。

ftyp3gp4 3gp43gp6 ワイド mdat

16進数

0000001866747970336770340000030033677034336770360000000877696465000392D86D6461740000

「mdat」タグの前の 4 バイトは、ファイルの最後にある別の「moov」タグの位置を表します。位置は通常、記録が終了したときに設定されますが、MediaRecorder はソケットをシークできないため、この場合、これらのバイトを正しい値に設定できません。

私の問題は、そのようなファイルをストリーミング可能にする方法を見つけることです。これには、録音が終了する前に再生することが含まれます。

于 2012-05-24T15:15:52.463 に答える
1

mp4box を使用してファイルを再構築してみてください。moov ボックスは、各オーディオおよびビデオ サンプルのインデックスを提供します。それがファイルの最後にあると、ストリーミングが難しくなります。

これが役立つかもしれません: http://boliston.wordpress.com/tag/moov-box/

またはこれ: mp4box -inter 0.5 some_file.mp4

(今は試す機会がありません)

アプリでこれが必要な場合は、mp4box を Android に移植する活動については知りません。

于 2013-04-03T20:43:39.960 に答える
0

私は今日同じことをしようとしましたが、mp4 はストリーミングするのがあまり簡単ではありません (いくつかの部分が最後に書かれる前に述べたように)。不可能とは言いませんが、少なくともかなり難しいようです。

したがって、新しい Android API (4.3) の回避策は次のようになります。

  • カメラ プレビューを SurfaceTexture に設定します: camera.setPreviewTexture
  • OpenGL と MediaCodex + Muxer を使用してこのテクスチャを記録します

このソリューションの欠点は、カメラのプレビュー サイズがビデオ サイズよりも小さくなる可能性があることです。これは、お使いのデバイスによっては最高解像度で録画できないことを意味します。ヒント: 一部のカメラは、より大きなプレビュー サイズをサポートしていないと言っていますが、サポートしているため、プレビュー サイズをビデオ サイズに設定するようにカメラを構成することができます。その場合は、camera.setParameters の RuntimeException をキャッチし、失敗した場合は、サポートされているプレビュー サイズのみを使用します。

SurfaceTexture から記録する方法のいくつかのリンク:

Bigflage: MediaCodec の優れた例。

Lablet の VideoRecorder クラス。

役に立つかもしれません: spydroid-ipcamera は MediaRecorder ソケットからデータを RTP ストリームとしてストリーミングしますが、それを MediaCodec にフィードする方法が見つかりませんでした。(私はすでに正しいNALユニットサイズを読んで行き詰まりました...)

于 2015-03-26T06:37:28.140 に答える