fbpixel
Etiquetas: , ,
0
(0)

Neste tutorial, veremos como enviar um fluxo de vídeo de uma máquina para outra usando FFMPEG. O envio de dados entre dois dispositivos, sejam eles quais forem, é um dos principais problemas dos objectos ligados (IoT). Se pretende criar uma câmara ligada que envia vídeo para uma máquina remota, este artigo deve interessar-lhe.

Instalando o ffmpeg

Numa máquina Linux

sudo apt-get install ffmpeg

Numa máquina Windows, siga este procedimento.

N.B.: se necessário numa máquina Linux sudo apt-get install v4l-utils

Obtenha as informações necessárias para a transmissão de vídeo

Para criar um fluxo de vídeo de uma máquina para outra, as máquinas devem estar ligadas à mesma rede (Wifi ou Ethernet).

Em primeiro lugar, é necessário obter o endereço IP da máquina cliente (que recebe o fluxo)

Introduzir um terminal de comando

ifconfig #pour une machine linux
ip addr # si ifconfig n'est pas disponible 

ou

ipconfig #pour une machine windows

Deve obter um endereço com o formato 192.168.X.X (no nosso caso 192.168.1.67)

Em seguida, recupere a fonte de vídeo. Para listar todas as entradas de vídeo numa máquina Linux

ls -l /dev/video*
lsusb #list usb devices
v4l2-ctl --list-devices #list video devices

Estes comandos devem ajudá-lo a identificar a fonte de vídeo. No nosso caso,

Para listar fontes de vídeo numa máquina Windows, pode utilizar o ffmpeg

ffmpeg -list_devices true -f dshow -i dummy

No nosso caso, video=”USB2.0 HD UVC WebCam “

Recuperar as opções e verificar os formatos e resoluções aceites pela câmara

no Linux

v4l2-ctl -d /dev/video0 --list-formats

no Windows

ffmpeg -f dshow -list_options true -i video="USB2.0 HD UVC WebCam"

Uma vez registados estes dados, podemos configurar o streaming.

Criar um fluxo de vídeo com o ffmpeg

Para criar um fluxo de vídeo, é necessário um emissor (servidor) e um recetor (cliente) que será reproduzido por dois terminais executados em dois computadores diferentes.

  • lado do servidor linux
ffmpeg -re -f v4l2 -i /dev/video5 -r 10 -f mpegts udp://192.168.1.67:8554?pkt_size=1316
  • Lado do servidor Windows
ffmpeg -f dshow -i video="USB2.0 HD UVC WebCam" -r 10 -f mpegts udp://192.168.1.67:8554?pkt_size=1316
  • lado do cliente
ffplay udp://127.0.0.1:8554

Nota: Pode testar o streaming numa única máquina utilizando o endereço IP da máquina em que está a trabalhar e utilizando dois terminais, um para o servidor e outro para o cliente.

Para obter estatísticas de vídeo, pode utilizar o comando ffprobe

ffprobe udp://127.0.0.1:8554

ou, para mais pormenores,

ffprobe -show_format -show_streams udp://127.0.0.1:8554

Reduzir o tempo necessário para receber fluxos de vídeo entre duas máquinas

Existe um atraso de cerca de 15 segundos entre a transmissão e a receção do vídeo. Pode valer a pena reduzir este atraso, consoante a aplicação.

No lado do servidor, os parâmetros que afectam a velocidade de transmissão são:

  • o tamanho da imagem (por exemplo, -s 800×600)
  • conversão do formato do codec (por exemplo, -c:v libx264)
  • o número de fotogramas por segundo ou framerate (por exemplo, -r 10)

Experimente jogar com estes parâmetros para reduzir o atraso, mantendo a qualidade suficiente.

ffmpeg -re -thread_queue_size 64 -s800x600 -i

No lado do cliente, existem várias opções que podem ser testadas a partir da documentação incluída nesta discussão.

ffplay -fflags nobuffer -probesize 32 -sync ext -vf setpts=0 udp:

Estas alterações às opções dos comandos ffmpeg e ffplay reduzem o atraso do fluxo de vídeo de 15 para cerca de 2 segundos.

Criar um fluxo HTTP com o ffmpeg

É possível criar um servidor de vídeo HTTP utilizando o VLC. A vantagem deste método é que o fluxo de vídeo pode ser transmitido para qualquer dispositivo.

  • lado do servidor linux
ffmpeg -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec copy -f mpegts -|vlc -I dummy - --sout='#std{access=http,mux=ts,dst=:8554}'
  • lado do cliente, é necessário especificar o endereço IP do servidor
ffplay http://192.168.1.9:8554

Criar um fluxo RTSP com o ffmpeg

É possível criar um servidor de vídeo HTTP utilizando o VLC. A vantagem deste método é que o fluxo de vídeo pode ser transmitido para qualquer dispositivo.

  • lado do servidor linux
ffmpeg -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec copy -f mpegts -|vlc -I dummy - --sout='#rtp{sdp=rtsp://:8554/} --sout-all --sout-keep'
  • lado do cliente, é necessário especificar o endereço IP do servidor
ffplay rtsp://192.168.1.9:8554/

Script Python para iniciar o streaming

Aqui está um script Python que lhe permitirá testar os diferentes métodos de streaming e os parâmetros do ffmpeg.

import subprocess

#UDP
#input client ip address here 192.168.1.9
stream_video="ffmpeg -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec copy -f mpegts udp://192.168.1.9:8554?pkt_size=1316"
#on client side ffplay udp://127.0.0.1:8554

#HTTP
stream_video="ffmpeg -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec copy -f mpegts -|vlc -I dummy - --sout='#std{access=http,mux=ts,dst=:8554}'"
#on client side ffplay http://192.168.1.73:8554

#RSTP
stream_video="ffmpeg -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vcodec copy -f mpegts -|vlc -I dummy - --sout='#rtp{sdp=rtsp://:8554/} --sout-all --sout-keep'"
#on client side ffplay rtsp://192.168.1.73:8554/ # don't forget / at the end

try:
	subprocess.call(stream_video,shell=True)
except:
	pass
print("Done")

Bónus: Apresentar o fluxo de vídeo FFMPEG com OpenCV

Uma vez que o fluxo de vídeo tenha sido estabelecido entre as duas máquinas, o OpenCV pode ser usado para ler e exibir as imagens do fluxo UDP.

import cv2

def main(args):

	#cap = cv2.VideoCapture(0) #default camera
	cap = cv2.VideoCapture('udp://127.0.0.1:8554')
	#cap = cv2.VideoCapture('http://192.168.1.9:8554')
	#cap = cv2.VideoCapture('rtsp://192.168.1.9:8554/')

	while(True):
		ret, frame = cap.read()
		if ret: #necessary if packet is lost
			frame=cv2.resize(frame, (800, 600)) 
			cv2.imshow('Capturing',frame)
			
		if cv2.waitKey(1) & 0xFF == ord('q'): #click q to stop capturing
			break

	cap.release()
	cv2.destroyAllWindows()
	return 0

if __name__ == '__main__':
    import sys
    sys.exit(main(sys.argv))

Bónus2 : Mostrar a hora no vídeo

Para mostrar a hora no vídeo, vamos utilizar o filtro drawtext do ffmpeg, que utiliza um determinado parâmetro de texto

  • fontfile: tipo de letra utilizado
  • fontsize: tamanho do texto
  • fontcolor: cor do texto
"drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf: text='%{localtime\:%T}': fontsize=24: fontcolor=white@0.8: x=7: y=460"

O filtro é aplicado com a etiqueta -vf. Aqui está o comando completo

ffmpeg -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vf "drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf: text='%{localtime\:%T}': fontsize=24: fontcolor=white@0.8: x=7: y=460" -vcodec copy -f mpegts udp://192.168.1.9:8554?pkt_size=1316

Em python

stream_cmd="""ffmpeg -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 -vf "drawtext=fontfile=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf: text='%{localtime\:%T}': fontsize=24: fontcolor=white@0.8: x=7: y=460" -vcodec copy -f mpegts udp://192.168.1.9:8554?pkt_size=1316"""

Útil para imitar uma câmara CCTV ou para comparar tempos de câmaras diferentes

Aplicações

Fontes

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?