Atualmente, estou empurrando um fluxo RTMP para o nginx 1.15.3 rodando no Ubuntu 18.04 LTS a partir de uma câmera raspberry pi 3 (que parece estar funcionando bem sozinha, eu posso puxar o fluxo sem problemas no VLC e verifique se está funcionando) com o pi usando este comando:
raspivid -w 640 -h 480 -fps 5 -t 0 -b 1800000 -o - | ffmpeg -y -framerate 5 -f h264 -i - -c:v copy -map 0:0 -f flv -rtmp_buffer 100 -rtmp_live live rtmp://10.2.10.149/cam01/test
Se eu tivesse que definir o argumento fps em raspivid para 25 e então me livrar do argumento ffmpeg framerate, isso seria traduzi-lo bem em um fluxo HLS com este comando sendo executado no servidor nginx:
ffmpeg -i rtmp://10.2.10.149/cam01/test -vcodec libx264 -vprofile baseline -acodec h264 -strict -2 -f flv rtmp://10.2.10.149/show1/stream1
No entanto, eu preciso dele na taxa de quadros mais baixa e parece que tentar fazer isso de alguma forma realmente perturba o ffmpeg, pois isso fará com que o fluxo fique muito lento, como se estivesse aguardando para carregar. Eu suspeito que tem algo a ver com o ffmpeg ter um framerate padrão de 25 ou algo assim, porque no fluxo RTMP, se eu fosse tentar definir apenas o argumento fps em raspivid para 5 e não incluir o argumento framerate no ffmpeg, ele seria faça o engate de vídeo por alguns segundos e então corra a 5 vezes a velocidade do vídeo por um segundo, já que o ffmpeg ainda está tentando rodar um vídeo de 25 fps.
Colocar o argumento framerate no comando de conversão ffmpeg parece tornar as coisas ainda piores e eu não entendo porque isso não está funcionando, já que parece funcionar muito bem para tantas outras pessoas. Eu usei este guia principalmente para tentar me ajudar em termos de configuração de nginx e outros enfeites: link
Também vou colocar o meu nginx.conf aqui para todo mundo ver, e note que estou tendo esse problema sempre que tento puxar o vídeo por uma página da Web ou com o VLC recebendo diretamente o fluxo da rede:
worker_processes auto;
events {
worker_connections 1024;
}
# RTMP configuration
rtmp {
server {
listen 1935; # Listen on standard RTMP port
chunk_size 4096;
application show1 {
live on;
# Turn on HLS
hls on;
hls_path /mnt/hls1/;
hls_fragment 3;
hls_playlist_length 60;
}
application show2 {
live on;
# Turn on HLS
hls on;
hls_path /mnt/hls2/;
hls_fragment 3;
hls_playlist_length 60;
}
application show3 {
live on;
# Turn on HLS
hls on;
hls_path /mnt/hls3/;
hls_fragment 3;
hls_playlist_length 60;
}
application show4 {
live on;
# Turn on HLS
hls on;
hls_path /mnt/hls4/;
hls_fragment 3;
hls_playlist_length 60;
}
application show5 {
live on;
# Turn on HLS
hls on;
hls_path /mnt/hls5/;
hls_fragment 3;
hls_playlist_length 60;
}
application show6 {
live on;
# Turn on HLS
hls on;
hls_path /mnt/hls6/;
hls_fragment 3;
hls_playlist_length 60;
}
application show7 {
live on;
# Turn on HLS
hls on;
hls_path /mnt/hls7/;
hls_fragment 3;
hls_playlist_length 60;
}
application cam01 {
live on;
record off;
}
application cam02 {
live on;
record off;
}
application cam03 {
live on;
record off;
}
application cam04 {
live on;
record off;
}
application cam05 {
live on;
record off;
}
application cam06 {
live on;
record off;
}
application cam07 {
live on;
record off;
}
}
}
http {
sendfile off;
tcp_nopush on;
default_type application/octet-stream;
server {
listen 80;
server_name localhost;
location / {
# Disable cache
add_header 'Cache-Control' 'no-cache';
# CORS setup
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length';
# allow CORS preflight requests
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
types {
application/dash+xml mpd;
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /mnt/;
location /index.html {
default_type "text/html";
}
location /testing.html {
default_type "text/html";
}
location /test.html {
default_type "text/html";
}
location /cam01.html {
default_type "text/html";
}
location /cam02.html {
default_type "text/html";
}
location /cam03.html {
default_type "text/html";
}
location /cam04.html {
default_type "text/html";
}
location /cam05.html {
default_type "text/html";
}
location /cam06.html {
default_type "text/html";
}
location /cam07.html {
default_type "text/html";
}
}
}
}
Se eu precisar incluir mais detalhes, sinta-se à vontade para me informar, eu só preciso que isso funcione corretamente, em vez de todas as questões que acabei de explicar, qualquer ajuda será apreciada, obrigado.
Editar 1: Eu também estou percebendo que em cima dos engates e recortes do fluxo usando o segundo comando como descrito anteriormente, ele parece ficar "preso" em um determinado quadro, às vezes, não tenho certeza se isso é mais útil ou não, só queria ter certeza de que tenho todas as informações que posso aqui.
Editar 2: Estou começando a acreditar que isso é mais um problema com o nginx porque quando eu aponto o primeiro comando para a localização / show1 / stream1 que converte o rtmp para hls sem executar o segundo comando que eu achava que era completamente necessário, estou recebendo o mesmo problema exato da mesma maneira. Eu não sei muito sobre o nginx e nada que eu esteja achando online está ajudando muito também. Eu apreciaria muito o insight, sei que hls sempre terá um grande atraso e não é isso que estou pedindo para consertar, estou pedindo para consertar os recortes e o engate.
Editar 3: Eu posso ter realmente rachado isso, eu notei no comando raspimiento, definindo a taxa de bits maior parece aliviar isso, no entanto, mesmo se eu definir a taxa de bits para um absurdo ou até mesmo não tão absurdo, mas Ainda assim, ainda assim, ocasionalmente, corta alguns quadros aleatoriamente a cada dois minutos e eu não sei exatamente por quê. Gostaria de receber algum insight.