Transcrição em tempo real para H264 + AAC no contêiner Matroska

2

Cenário

Eu tenho uma biblioteca de filmes que pretendo tornar fluível para meu tablet Android usando o VLC para reprodução. Eu quero usar H264 + AAC para melhor qualidade visual possível através de uma conexão de internet móvel. Eu também gostaria de usar um contêiner Matroska que suporta legendas de texto em oposição a legendas de bitmap suportadas pelo MPEG2TS.

Eu tenho o Mediatomb instalado e o UPnP está funcionando como deveria, posso transmitir vídeo e áudio sem transcodificação.

Problema

Eu posso transcodificar e diminuir a resolução para MPEG2 bem. Mas a reprodução do H264 pára após 10-40 segundos exatamente no mesmo lugar, em qualquer vídeo, mas em locais diferentes para cada vídeo. A reprodução nem começa no VLC do PC (pára após o primeiro quadro).

Configs

Estou usando este script

#!/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

Minha configuração de mediatomb com seção relevante:

<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>

Se eu fizer tail -f /store/tmp/log , poderei ver que o processo FFMPEG ainda está sendo codificado mesmo depois que a reprodução for interrompida no tablet. De fato, é muito feliz mastigar. E também está codificando a uma taxa que é mais rápida que o material de origem, por isso não fica para trás. A reprodução no tablet é suave até que pare de repente.

Eu tentei usar diferentes parâmetros predefinidos, perfil e ajuste sem sucesso, o tempo até que o congelamento pareça ser inversamente proporcional à velocidade de execução do codificador (alta velocidade de codificação, pouco tempo para congelar)

    
por Emily L. 27.09.2013 / 00:04

1 resposta

4

Ajuste o fluxo h264 para ser transmitido:

Aparentemente, o codec h264 tem um modo especial que é necessário para que ele seja eficiente e você o habilita com: -bsf:v h264_mp4toannexb

Script

O script que eu uso para configurar um tubo de streaming matroska H264 + AAC é este:

#!/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

TODO:

Faça com que ele leia as legendas de arquivos externos, se encontradas, e adicione-as ao fluxo matroska. Faça com que não transcodifique o fluxo de áudio se já estiver em um formato adequado.

    
por 29.09.2013 / 20:00