Streaming com FFMpeg: Splashscreen?

1

Eu tenho experimentado com streaming via FFMpeg. Eu amo o quão poderoso é! Atualmente eu tenho configurado para que ele transmite minha tela e adiciona uma sobreposição para a minha webcam. No entanto, há uma coisa que gostaria de poder fazer que não consigo entender: crie uma tela inicial sob demanda.

Talvez isso seja melhor explicado pelo exemplo. Digamos que você esteja transmitindo um jogo ou algo assim por Twitch por muito tempo. Então você tem que se afastar. Você poderia

  1. Apenas vá embora ou
  2. Jogue um "Volto já!" tela inicial ou algo assim, talvez com um pouco de música (eu tenho essa parte descoberta graças à grandiosidade do Pulseaudio)

Achei que a melhor maneira de conseguir isso era por meio de uma segunda sobreposição que sobrepõe a sobreposição de tela / webcam.

Eu tentei adicionar uma terceira entrada semelhante a esta:

 ffmpeg -f v4l2 -i /dev/video0 -f xllgrab -i :0.0+738,0 \
        -i ~/splashscreen.png -loop 1 \
        -filter_complex "[0:1][0:0]overlay=0:0[out];[out][2:0]overlay=0:0[final]" \
        -f flv ~/Videos/test.flv 

Isso requer uma versão mais nova do ffmpeg do que no repositório Saucy.

E funcionou, pois a tela inicial era transparente. Eu pensei em fazer algo inteligente e trocar em uma imagem não transparente quando eu precisei da tela inicial, mas o ffmpeg armazena em cache a imagem em loop ou a ignora quando de repente não consegue encontrar o arquivo por uma breve instância.

A segunda maneira que pensei foi, talvez, usar um pipe nomeado e usar outra instância do ffmpeg para pipilar, eles sobrepõem a tela inicial quando eu preciso, mas pelo que eu li, se o ffmpeg não encontrar nenhum dado no pipe não continuará processando o restante do vídeo, em vez disso, ele só colocará quadros quando puder extrair todas as fontes de entrada.

Se houver algum ffmpeg gurus por aí, adoraria ouvir algumas ideias!

    
por Chuck R 24.03.2014 / 09:25

1 resposta

3

Eu fiz isso! Concedido, exigiu alguns backflips, mas nem por isso funciona = D

Aqui está o script que usei:

#!/bin/bash

#NOTE: The framerate throttling can probably be removed due to the limit in
#the amount of data that can be written to a pipe before it blocks. My
#streams are at 1920x1080 and cat only puts 5 frames onto the pipe
#before it hangs waiting for a program to tread the pipe. I found this odd
#since my splash screen images were only 8k, whereas the pipe size is 1M.
#Therefore, it might be highly dependent on the resolution of your splash
#images. By removing the FPS logic of this script, a higher potential
#framerate can be achieved by the script if that's necessary.

#This is my third FFMpeg input. My other two are at framerates of
#10 (screen) and 30 (webcam). My output is 10 FPS. I had originally
#set this to 10 as well, but it caused FFMpeg to choke and start dropping
#frames for some reason, so I just added 5 since it's a common denominator
#of both 10 and 30. +2 may have also worked, but that seemed a little too
#close for me since even 11 had issues with output framerate, hovering
#around 9.9 FPS rather than the target 10 FPS.

framerate=15

#Tracks how many frames we've written this second
files_this_second=0
this_second=$(date +%s)

while [ 1 ]
do
  #Haven't written all the frames for this second
  if [ $files_this_second -lt $framerate ]
  then
    if [ ! -f /file/to/test/to/throw/up/splash ]
    then
      #Output the transparent "splash screen" (no splash screen)
      cat /path/to/a/transparent.png
    else
      #Output the splash screen
      cat /path/to/a/splashscreen.png
    fi
    files_this_second=$(($files_this_second + 1))
  else
    #The second has changed
    if [ "$(date +%s)" != "$this_second" ]
    then
      this_second=$(date +%s)
      files_this_second=0
    fi
  fi
done

Eu posso então alimentar a saída deste script no FFMpeg da seguinte forma:

splash.sh | ffmpeg -f image2pipe -vcodec png -framerate 15 -i - (some other video source and parameters) -filter_complex "[1:0]setpts=PTS-STARTPTS[video];[0:0]setpts=PTS-STARTPTS[splashscreen];[video][splashscreen]overlay=0:0" (output format options and file)

Em seguida, configuro uma tecla de atalho para executar outro script simples:

#!/bin/bash

if [ -f /file/to/test/to/throw/up/splash ]
then
  rm /file/to/test/to/throw/up/splash
else
  touch /file/to/test/to/throw/up/splash
fi

Quando eu quero jogar a tela inicial, eu bato na tecla de atalho. Quando eu quero derrubar, eu acerto a tecla de atalho novamente.

Isso é útil para algumas coisas:

  1. Uma tela inicial (como mencionado)
  2. Apagando a tela ao inserir senhas ou algo

Ele também ignora o problema de as imagens ficarem armazenadas em cache, como na minha pergunta acima, então você simplesmente teria que substituir a imagem por outra para definir outra tela inicial.

Eu acho que é brilhante! O que vocês acham?

NOTA: Estou usando uma versão auto-compilada do FFMpeg porque a disponível nos repositórios Saucy está bastante desatualizada. Além disso, o formato image2pipe é não documentado que posso encontrar.

    
por Chuck R 26.03.2014 / 08:42