11

セグメンターを使用して、MPEG2TsファイルをHTTPライブストリーミング用の一連のメディアセグメントにセグメント化します

前のセグメントに続く各セグメントの開始時刻(例:セグメントの開始時刻:00:00,00:10,00:20,00:30、...)

(Ubuntuの場合)

質問は:

ffmpegを使用してメディアセグメントの1つをトランスコードすると(例:800kbpsから200kbps)

トランスコードされたメディアセグメントの開始時刻は0にリセットされます

例:3番目のセグメントをトランスコードすると、

セグメントの開始時刻が次のように変更されます: 00:00,00:10、00:00、00:30、..。

トランスコードされたメディアセグメントを再生すると、プレーヤーがフリーズします

同じ開始時間でメディアファイルをトランスコードするための解決策はありますか?

ffmpegがセグメントのPTS(プレゼンテーションタイムスタンプ)をリセットしたのだと思います

しかし、私はそれを修正する方法がわかりません...

これが私のffmpegコマンドです(250k bpsにトランスコードします)

============================

ffmpeg -y -i sample-03.ts -f mpegts -acodec libfaac -ar 48000 -ab 64k -vcodec libx264 -b 250k -flags +loop -cmp +chroma \
 -partitions +parti4x4+partp8x8+partb8x8 -subq 7 -trellis 0 -refs 0 -coder 0 -me_range 16 -keyint_min 25 \
 -sc_threshold 40 -i_qfactor 0.71 -maxrate 250k -bufsize 250k -rc_eq 'blurCplx^(1-qComp)' -qcomp 0.6 \
 -qmin 10 -qmax 51 -qdiff 4 -level 30 -aspect 320:240 -g 30 -async 2 sample.ts

============================

ヘルプ!

ありがとう

4

5 に答える 5

3

h264エンコードセグメントの直接パケットタイムシフト

結局、ffmpeg libavformat / avcodecライブラリとリンクして読み込み、パケットタイムヘッダーを直接シフトしました。オフセット時間は秒単位で指定されます

unsigned int tsShift = offsetTime * 90000; // h264 defined sample rate is 90khz

そしてさらに下

do {
    double segmentTime;
    AVPacket packet;

    decodeDone = av_read_frame(pInFormatCtx, &packet);
    if (decodeDone < 0) {
        break;
    }

    if (av_dup_packet(&packet) < 0) {
        cout << "Could not duplicate packet" << endl;
        av_free_packet(&packet);
        break;
    }

    if (packet.stream_index == videoIndex && (packet.flags & AV_PKT_FLAG_KEY)) {
        segmentTime = (double)pVideoStream->pts.val * pVideoStream->time_base.num / pVideoStream->time_base.den;
    }
    else if (videoIndex < 0) {
        segmentTime = (double)pAudioStream->pts.val * pAudioStream->time_base.num / pAudioStream->time_base.den;
    }
    else {
        segmentTime = prevSegmentTime;
    }

    // cout << "before packet pts dts " << packet.pts << " " << packet.dts;
    packet.pts += tsShift;
    packet.dts += tsShift;
    // cout << " after packet pts dts " << packet.pts << " " << packet.dts << endl;


    ret = av_interleaved_write_frame(pOutFormatCtx, &packet);
    if (ret < 0) {
        cout << "Warning: Could not write frame of stream" << endl;
    }
    else if (ret > 0) {
        cout <<  "End of stream requested" << endl;
        av_free_packet(&packet);
        break;
    }

    av_free_packet(&packet);

} while (!decodeDone);

mpegtsシフターソース


ラウンドアバウトでストリームをシフト

しかし、時間デルタは正確には私が指定したものではありません

方法は次のとおりです

  1. 最初に元のtsファイルをraw形式に変換します

    ffmpeg -i original.ts original.avi

  2. setptsフィルターを適用し、エンコードされた形式に変換します(これは、フレームレートと目的のタイムシフトによって異なります)

    ffmpeg -i original.avi -filter:v'setpts = 240 + PTS' -sameq -vcodec libx264 shift.mp4

  3. 結果のshift.mp4をセグメント化します

    ffmpeg -i shift.mp4 -qscale 0 -bsf:v h264_mp4toannexb -vcodec copy -an -map 0 -f segment -segment_time 10 -segment_format mpegts -y ./temp-%03d.ts

最後に作成されたセグメントファイル(私の場合はtemp-001.ts)は、タイムシフトされました

問題:この方法は、単にいくつかのtsパケット時間をシフトするだけでは鈍感であり、新しいtsファイルに必要な正確な10秒ではなく、10.5+の開始時間が発生しました。


元の提案は以下のように機能しませんでした

ffmpeg -itoffset prevTime (rest of ts gen args) | ffmpeg -ss prevTime -i _ -t 10 stuff.ts

prevTimeは、以前のすべてのセグメントの期間です

2番目のffmpeg-ss呼び出しは、時間0(または場合によっては1.4秒-おそらく単一のtsファイルの構築におけるバグ)を基準にして出力mpegtsファイルを作成するので良くありません

于 2013-03-10T12:21:42.657 に答える
2

IMO-セグメントのシリアル化されたリストがあり、それらを連結したい。

セグメントのシリアル順序が連結によって保持されている限り、これで終わりです。

連結できるように、各セグメントエントリで実行するプロセス...

getVideoRaw to its own file
getAudioRaw to its own file

すべてのセグメントを生に分割した場合、これを実行します。

concatenate video preserving serialized order so video segments remain correct order in videoConCatOUT.

concatenate the audio as above

次に、それぞれのconcatOUTファイルを単一のコンテナにマルチプレクサします。

これはスクリプト化でき、標準に従うことができます。ConcatのffmpegFAQの例

ここの「3.14.4」セクションを参照してください

'tail'cmdと行番号の削除についての説明に注意してください。concatプロセスへの最初のセグメント入力を除くすべてから1。

于 2013-03-14T21:55:19.053 に答える
1

setptsフィルタを見てください。これにより、各ピースのPTSを十分に制御できるようになります。

于 2012-05-09T22:26:58.407 に答える
1

セグメント化する前にトランスコードする必要があります。個々のセグメントをトランスコードする場合、毎回新しいtsストリームが作成され、ts時間データはコピーされません。

于 2012-05-11T07:47:34.350 に答える
1

セグメンターマルチプレクサhttps://ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegmentがあります。

于 2013-08-12T14:07:29.940 に答える