транскодирование ffmpeg сбросить время начала файла

Я использую segmenter, чтобы сегментировать мой файл MPEG 2 Ts на серию медиа-сегментов для потоковой передачи HTTP в реальном времени.

и время начала каждого сегмента, следующего за предыдущим (например: время начала сегментов: 00: 00,00: 10,00: 20,00: 30, ...)

(В Ubuntu)

Вопрос в том:

Когда я использую ffmpeg для перекодирования одного из сегментов мультимедиа (например, от 800 кбит / с до 200 кбит / с)

время начала транскодированного сегмента мультимедиа будет сброшено на 0

Пример: когда я перекодирую третий сегмент,

время начала сегментов меняется на: 00: 00,00: 10, 00:00, 00: 30, ...

Это вызывает зависание моего плеера после воспроизведения транскодированного медиафрагмента.

Есть ли какое-нибудь решение для перекодирования медиафайлов с одинаковым временем начала?

Я предполагаю, что ffmpeg сбрасывает PTS (временную метку презентации) сегмента

Но я не знаю, как это исправить ...

вот моя команда ffmpeg (перекодировать до 250 Кбит / с)

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

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

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

Помощь!

Благодарность


person diousk    schedule 07.03.2012    source источник


Ответы (5)


прямой пакетный сдвиг во времени сегментов, закодированных в формате 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 в необработанный формат

    ffmpeg -i original.ts original.avi

  2. применить фильтр настроек и преобразовать в закодированный формат (это будет отличаться в зависимости от частоты кадров и желаемого временного сдвига)

    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, и это привело к времени запуска 10,5+ вместо точно 10 секунд, желаемых для нового файла ts


исходное предложение не сработало, как описано ниже

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

prevTime - продолжительность всех предыдущих сегментов

бесполезно, поскольку второй вызов ffmpeg -ss делает выходной файл mpegts относительно времени 0 (или иногда 1,4 секунды - возможно, ошибка в создании отдельных файлов ts)

person Mark Essel    schedule 10.03.2013

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 в один контейнер.

Это может быть написано сценарием и может следовать за std. пример в FAQ по ffmpeg на Concat

см. раздел "3.14.4" здесь

Обратите внимание на cmd «хвост» и пояснение о пропадании строки №. 1 из всех, кроме первого сегмента, входящего в процесс concat ...

person Robert Rowntree    schedule 14.03.2013
comment
Спасибо, Роберт, но текущее узкое место - конкатенация и повторное объединение. Цель (по крайней мере, для меня) - выполнить сегментацию в разных процессах в разных системах, а затем выполнить потоковую передачу из одного списка m3u8. - person Mark Essel; 15.03.2013
comment
кстати, я закончил тем, что написал код в ответе ниже, чтобы сделать именно то, что я хотел (временные метки сдвига), увидеть прямое временное смещение пакета для закодированных сегментов h264 - person Mark Essel; 15.03.2013

Вы должны перекодировать перед сегментацией. Когда вы перекодируете отдельный сегмент, он каждый раз создает новый поток ts, и данные времени ts не копируются.

person vipw    schedule 11.05.2012

Взгляните на фильтр setpts. Это должно дать вам полный контроль над PTS каждого предмета.

person blahdiblah    schedule 09.05.2012

есть мультиплексор сегментов https://ffmpeg.org/ffmpeg-formats.html#segment_002c-stream_005fsegment_002c-ssegment, который может помочь вам с тем, что вам нужно ...

person rogerdpack    schedule 12.08.2013