2

MediaCodecAPIを使用してAndroidにメディアプレーヤーを実装しようとしています。

私は 3 つのスレッドを作成しましaudiovideo

スレッド 2 :audioコーデックの出力バッファをデキューし、AudioTrackクラスの書き込みメソッドを使用してレンダリングする

スレッド 3 :videoコーデックの出力バッファをデキューし、releaseBufferメソッドを使用してレンダリングするには

フレーム間audioの同期を達成する際に多くの問題に直面しています。videoフレームをドロップすることはなくaudio、フレームをレンダリングする前にvideo、デコードされたフレームが 3 ミリ秒以上遅れているかどうかをチェックします。

との違いを見つけるには、audiovideoのロジックを使用します

public long calculateLateByUs(long timeUs) {
        long nowUs = 0;

        if (hasAudio && audioTrack != null) {
            synchronized (audioTrack) {
                if(first_audio_sample && startTimeUs >=0){
                    System.out.println("First video after audio Time Us: " + timeUs );
                    startTimeUs = -1;
                    first_audio_sample = false;
                }

            nowUs = (audioTrack.getPlaybackHeadPosition() * 1000000L) /
                    audioCodec.format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
        }

    } else if(!hasAudio){
        nowUs = System.currentTimeMillis() * 1000;
        startTimeUs = 0;

    }else{
        nowUs = System.currentTimeMillis() * 1000;

    }

    if (startTimeUs == -1) {
        startTimeUs = nowUs - timeUs;
    }
    if(syslog){
        System.out.println("Timing Statistics:");             
        System.out.println("Key Sample Rate :"+ audioCodec.format.getInteger(MediaFormat.KEY_SAMPLE_RATE) +  " nowUs: " + nowUs + " startTimeUs: "+startTimeUs + " timeUs: "+timeUs + " return value :"+(nowUs - (startTimeUs + timeUs)));
    }

    return (nowUs - (startTimeUs + timeUs));
}

timeUsビデオ フレームの表示時間 (マイクロ秒) です。nowUs再生中のマイクロ秒単位のデュレーションが含まれているはずaudioです。常に維持する必要があるとフレームstartTimeUsの初期の違いです。audiovideo

最初の if ブロックは、audioトラックが実際に存在し、それが初期化されているかどうかをチェックし、存在しない 場合(first else)が設定され、初期ギャップがゼロに設定されてnowUsいることから計算しての値を設定します。メイン関数でゼロに初期化されます。audiotrack audionowUsSystemTimestartTimeUs

同期ブロックの if ブロックは、最初にレンダリングされるフレームが でaudioaudioフレームが後で結合する場合に使用されます。first_audio_sampleflag は最初は true に設定されています。

不明な点があればお知らせください。

また、ビデオ コーデックを使用して av ファイルのメディア プレーヤーが実装されているオープン ソース リンクを知っていれば、それは素晴らしいことです。

4

1 に答える 1

0

の最新リリースのいずれかに取り組んでいる場合は、から直接Android取得することを検討できます。詳細については、このドキュメントを参照してください。同様に、 via を取得することも検討できます。audioTimeStampAudioTracksampling rategetSampleRate

アルゴリズムを続行したい場合は、このネイティブの例で比較的類似した実装を検討できます。SimplePlayerプレーヤー エンジンを採用MediaCodecして実装し、av 同期セクションも備えています。同期が実行されるコードのこのセクションを参照してください。良い参考になると思います。

于 2014-03-11T00:47:41.263 に答える