Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[question] Handling chunked POST bodies sent to /pub endpoints #312

Open
jaygooby opened this issue Aug 22, 2024 · 3 comments
Open

[question] Handling chunked POST bodies sent to /pub endpoints #312

jaygooby opened this issue Aug 22, 2024 · 3 comments

Comments

@jaygooby
Copy link

I'm trying to use ffmpeg's -progress URL option to send rendering progress data to a /pub channel.

Here's a simple example that generates 30 seconds of black h264 video:

ffmpeg -y -progress "http://127.0.0.1/pub?id=ffmpeg" -t 30 -f lavfi -i color=c=black:s=640x480 -c:v libx264 -tune stillimage -pix_fmt yuv420p black.mp4

The -progress URL is a /pub channel: http://127.0.0.1/pub?id=ffmpeg

My nginx location looks like:

location = /pub {

  # We're not using a proxy, just the push-stream module
  # proxy_buffering off;
  # proxy_set_header Connection "";
  # ensure http 1.1 or buffering always occurs
  # proxy_http_version 1.1;

  # we don't care about client max body size
  client_max_body_size 0;

  # don't do this, nothing comes through at all
  # client_body_buffer_size 0;

  # should be on by default
  chunked_transfer_encoding on;

  # turn off client request buffering
  proxy_request_buffering off;

  # activate publisher (admin) mode for this location
  push_stream_publisher admin;

  # query string based channel id
  push_stream_channels_path $arg_id;

  # access control
  allow all; # don't do this in prod!
}

ffmpeg sends its progress data as a chunked POST body. I've tested that it sends as it happens, by capturing its output with netcat:

# start "server"
nc -l 7000 > ffmpeg.http.log &

# render 30 seconds of blank h264 sending progress to the server
ffmpeg -y -progress http://127.0.0.1:7000 -t 30 -f lavfi -i color=c=black:s=640x480 -c:v libx264 -tune stillimage -pix_fmt yuv420p black.mp4

# cat the "server" log
cat ffmpeg.http.log

You can see the chunked POST headers, followed by the data:

POST / HTTP/1.1
Transfer-Encoding: chunked
User-Agent: Lavf/58.29.100
Accept: */*
Connection: close
Host: 127.0.0.1:7000
Icy-MetaData: 1

c5
frame=346
fps=0.00
stream_0_0_q=28.0
bitrate=   0.0kbits/s
total_size=48
out_time_us=11840078
out_time_ms=11840078
out_time=00:00:11.840078
dup_frames=0
drop_frames=0
speed=23.7x
progress=continue

c7
frame=708
fps=704.69
stream_0_0_q=28.0
bitrate=   0.0kbits/s
total_size=48
out_time_us=26320078
out_time_ms=26320078
out_time=00:00:26.320078
dup_frames=0
drop_frames=0
speed=26.2x
progress=continue

c5
frame=750
fps=680.10
stream_0_0_q=-1.0
bitrate=   7.7kbits/s
total_size=28599
out_time_us=29880078
out_time_ms=29880078
out_time=00:00:29.880078
dup_frames=0
drop_frames=0
speed=27.1x
progress=end

0

The problem I've got is that with that ^^^ nginx location block, nothing appears in the channel until ffmpeg closes the connection. I've tried with the commented out proxy_ directives too, just in case. Any ideas about what's missing so the client's POST body isn't buffered?

@sunnychun
Copy link

sunnychun commented Aug 22, 2024 via email

@wandenberg
Copy link
Owner

Hi @jaygooby
it looks like the issue is because ffmpeg is using a chunked post, meaning it opens a connection and sends data without closing the connection.
The module is not designed for that.
Chunked posts can be misinterpreted, like where the real message starts/finishes.
I don't know this feature of ffmpeg. Try to check if it has options to not use chunked posts.
If it does not, I guess that the solution would be to do a simple custom application to listen to the ffmpeg post, break down each group of progress notifications, and then post to the nginx using the module to broadcast it to all your subscribers.
Please, let me know if this makes sense for you. I can try to help with this custom application.

@jaygooby
Copy link
Author

jaygooby commented Aug 23, 2024

@wandenberg thanks for the confirmation :(

I know there's no way to disable the ffmpeg chunked POST, so I'll see what else I can do…

ffmpeg can also stream its progress to a pipe or fifo; I'll see if I can intercept the data that way and POST each update separately

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants