Транскодирование в реальном времени в H264+AAC в контейнере Matroska
сценарий
У меня есть библиотека фильмов, которую я хочу сделать для моего планшета Android с помощью VLC для воспроизведения. Я хочу использовать H264+AAC для наилучшего визуального качества через мобильное интернет-соединение. Я также хочу использовать контейнер Matroska, который поддерживает текстовые субтитры, а не растровые субтитры, которые поддерживает MPEG2TS.
У меня установлен Mediatomb и UPnP работает как надо, я могу нормально транслировать видео и аудио без транскодирования.
проблема
Я могу нормально транскодировать и преобразовывать в MPEG2. Но воспроизведение H264 останавливается через 10-40 секунд в одном и том же месте каждый раз для любого видео, но в разных местах для каждого видео. Воспроизведение даже не начинается на VLC на ПК (останавливается после первого кадра).
Configs
Я использую этот скрипт
#!/bin/bash
LINES=720
PRESET=veryfast
PROFILE=main
TUNE=zerolatency
AUDIO="-c:a libfaac -b:a 128k -ar 48000 -ac 2 -async 1"
# Works well
VIDEO="-c:v mpeg2video -b 8192k"
# Freezes after a few seconds seconds.
#VIDEO="-c:v libx264 -preset ${PRESET} -tune ${TUNE} -profile ${PROFILE}"
SUBTITLES="-c:s copy"
exec /usr/bin/ffmpeg -threads 2 -i "${1}" -filter:v scale=-1:720 $VIDEO \
$AUDIO $SUBTITLES -f matroska -y "${2}" &> /store/tmp/log
Мой конфиг mediatomb с соответствующим разделом:
<profile name="h264stream" enabled="yes" type="external">
<mimetype>video/x-matroska</mimetype>
<accept-url>no</accept-url>
<first-resource>yes</first-resource>
<hide-original-resource>yes</hide-original-resource>
<accept-ogg-theora>yes</accept-ogg-theora>
<sample-frequency>48000</sample-frequency>
<audio-channels>2</audio-channels>
<agent command="/etc/mediatomb/ffmpeg.sh" arguments="%in %out"/>
<buffer size="104857600" chunk-size="262144" fill-size="524288"/>
</profile>
Если я сделаю tail -f /store/tmp/log
Я вижу, что процесс FFMPEG все еще кодируется даже после остановки воспроизведения на планшете. На самом деле, он довольно счастливо жует. И это также кодирование со скоростью, которая быстрее, чем исходный материал, поэтому он не отстает. Воспроизведение на планшете происходит плавно до внезапной остановки.
Я пытался использовать разные параметры пресета, профиля и настройки безрезультатно, время до его зависания кажется обратно пропорциональным скорости работы кодера (высокая скорость кодирования, короткое время остановки)
1 ответ
Отрегулируйте поток h264, чтобы он был потоковым:
По-видимому, кодек h264 имеет специальный режим, который требуется для его эффективной потоковой обработки, и вы включаете его с помощью: -bsf:v h264_mp4toannexb
скрипт
Сценарий, который я использую для настройки потокового канала Matroska H264+AAC:
#!/bin/bash
# ----------------------------------------------------------------------------
# This script is a helper to transcode a video to H264+AAC with subtitles to a
# Matroska (.mkv) container that is suitable for live streaming to a mobile
# device. It will transcode media that is not H264 or that has too high
# resolution. It will not upsample content.
#
# Other suitable containers (and reasons for not using them) include:
# * ASF (Microsoft, proprietary)
# * MPEG2 Transport Stream (Standard, only supports bitmap subtitles)
# * WebM (Has no support for metadata)
# * DivX (Can't contain H264)
# * FLV (Proprietary Bad support on target device)
# * MP4 (Only bitmap subtitles, didn't work for streaming with FFMPEG)
# * OGG (No support for H264)
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Video options
# ----------------------------------------------------------------------------
LINES=720
# One of: ultrafast,superfast, veryfast, faster, fast, medium, slow, slower,
# veryslow or placebo
PRESET=ultrafast
# One of: baseline, main, high, high10, high422 or high444
PROFILE=high10
# One of: film animation grain stillimage psnr ssim fastdecode zerolatency
TUNE=zerolatency
# ----------------------------------------------------------------------------
# Audio options
# ----------------------------------------------------------------------------
AUDIO="-c:a libfaac -b:a 128k -ar 48000 -ac 2 -async 1"
SUBTITLES="-c:s copy"
# ----------------------------------------------------------------------------
# Read input video parameters
# ----------------------------------------------------------------------------
IN_RESOLUTION=`/usr/bin/ffmpeg -i "${1}" 2>&1 | grep Video | \
perl -lane 'print $1 if /(\d+x\d+)/'`
IN_CODEC=`/usr/bin/ffmpeg -i "${1}" 2>&1 | grep Video | \
perl -lane 'print $1 if /Video: (\S+)/'`
IN_DIMS=(${IN_RESOLUTION//x/ })
V_TRANSCODE="-c:v libx264 -bsf:v h264_mp4toannexb -preset ${PRESET} \
tune ${TUNE} -profile:v ${PROFILE}"
V_COPY="-c:v copy -bsf:v h264_mp4toannexb"
if [ "${IN_DIMS[1]}" > "${LINES}" ]; then
SCALE="-filter:v scale=-1:${LINES} ${OPT_TRANSCODE}"
else
if ["${IN_CODEC}" != "h264" ]; then
VIDEO=$OPT_TRANSCODE
else
VIDEO=$V_COPY
fi
fi
exec /usr/bin/ffmpeg -threads `nproc` -i "${1}" $VIDEO $AUDIO $SUBTITLES \
-f matroska -y "${2}" &> /store/tmp/log
СДЕЛАТЬ:
Заставьте его читать субтитры из внешних файлов, если они найдены, и добавляйте их в поток matroska. Сделайте так, чтобы он не транскодировал аудиопоток, если он уже находится в подходящем формате.