Convert Byte-range to Time-range in html <video

2020-06-23 08:17发布

问题:

I have some sever-side code that currently supports the http byte range requests without an issue. However, I want to be able to transcode the video file (which is located on-disk) on-the-fly with ffmpeg before I send the transcoded chunk to the client, but ffmpeg requires I give it a seek time whereas I get byte ranges from the client. How would I be able to figure out the time range (seek time) of a video file given the byte range from the client browser?

I have already looked at this question which assumes the server already knows the specified time.

I am open to using an html5 video player which supports the use of time ranges to request data instead of byte ranges, but I have been unable to find an implementation or figure out how the javascript side of buffering <video> works.

回答1:

You can run ffprobe and analyze its output to identify the timestamps.

Basic command is

ffprobe -i in.mp4 -show_entries packet=pos,pts_time,flags -select_streams v -of compact=p=0:nk=1 -v 0

This produces

0.000000|48|K_
0.133333|956|__
0.066667|996|__
0.033333|1053|__
0.100000|1602|__
0.266667|1811|__
0.200000|2371|__
0.166667|2746|__
0.233333|3294|__
....

The first column is the video frame timestamp, the 2nd is the byte offset for that frame and the 3rd is whether the frame is a keyframe.

Since you can only cut video at keyframes, when copying the stream, you will either have to cut at a timestamp whose flag is K or use the argument in the command below:

ffmpeg -ss X -i in.mp4 -c copy -avoid_negative_ts make_zero out.mp4

This is not needed if you're transcoding the video stream.