ffmpeg转码重置文件的开始时间

dio*_*usk 11 transcode ffmpeg http-live-streaming

我使用分段器将我的MPEG 2 Ts文件分割成一系列用于HTTP直播的媒体段

并且每个段的开始时间跟在前一段之后(例如:段的开始时间:00:00,00:10,00:20,00:30,......)

(在Ubuntu中)

问题是:

当我使用ffmpeg转码其中一个媒体片段(ex 800k bps到200k bps)

转码媒体段的开始时间将重置为0

例如:当我转码第三段时,

开始段的时间改变为: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
Run Code Online (Sandbox Code Playgroud)

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

救命!

谢谢

Mar*_*sel 3

h264 编码片段的直接数据包时移

我最终链接到 ffmpeg libavformat/avcodec 库来读入,并直接移动数据包时间标头。偏移时间以秒为单位指定

unsigned int tsShift = offsetTime * 90000; // h264 defined sample rate is 90khz
Run Code Online (Sandbox Code Playgroud)

以及下面进一步

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);
Run Code Online (Sandbox Code Playgroud)

mpegts 移位器源


以一种迂回的方式改变了流

但时间增量并不完全是我指定的

就是这样

  1. 首先将原始ts文件转换为raw格式

    ffmpeg -i 原始.ts 原始.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_time 10 -segment_format mpegts -y ./temp-%03d.ts

最后创建的段文件(在我的例子中是 temp-001.ts)是时移的

问题:这种方法对于仅仅移动一些 ts 数据包时间来说感觉很迟钝,并且它导致了 10.5+ 的开始时间,而不是新 ts 文件所需的正好 10 秒


最初的建议不起作用,如下所述

ffmpeg -itoffset prevTime (rest of ts gen args) | ffmpeg -ss prevTime -i _ -t 10 stuff.ts
Run Code Online (Sandbox Code Playgroud)

prevTime 是所有先前片段的持续时间

没有什么好处,因为第二个 ffmpeg -ss 调用使输出 mpegts 文件相对于时间 0 (或有时 1.4 秒 - 可能是单个 ts 文件构造中的错误)