Skip to content

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

@jaygooby

Description

@jaygooby

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions