Skip to content

Instantly share code, notes, and snippets.

@rlan
Last active September 13, 2023 23:00
Show Gist options
  • Save rlan/ab255879c2304a25928ddb190de6b552 to your computer and use it in GitHub Desktop.
Save rlan/ab255879c2304a25928ddb190de6b552 to your computer and use it in GitHub Desktop.
Convert video to jpg and back using ffmpeg

Video and JPG conversion using FFMPEG

Grab one frame from video

#!/bin/sh -x
# $1 - input video file, e.g. video.mp4
# $2 - timestamp, e.g. 00:33
# $3 - output image file, e.g. output.jpg
ffmpeg -ss $2 -i $1 -vframes 1 -q:v 2 $3

Grab all frames from video

#!/bin/sh -x
# $1 - input file, e.g. input.mp4
ffmpeg -i "$1" -q:v 2 %06d.jpg

Combine jpg files into one video

ffmpeg -f image2 -framerate 30 -i %06d.jpg -c:v libx264 out.mp4
@nallwhy
Copy link

nallwhy commented Feb 16, 2022

--ss -> -ss

@pidgeon777
Copy link

How do you convert images back to video using the same framerate as the original video?

@rlan
Copy link
Author

rlan commented May 10, 2022

How do you convert images back to video using the same framerate as the original video?

@pidgeon777 AFAIK, the frame rate is not saved in the extracted jpg files. So one has to enter that number on the command line when converting back to video. The frame rate is reported by ffmpeg when extraction is done in the first place.

@rlan
Copy link
Author

rlan commented May 10, 2022

--ss -> -ss

Fixed and verified in ffmpeg version 5.0.1.
Thank you @nallwhy

@ankurbhatia24
Copy link

Have you faced any color/brightness changes when encoding video from frames vs the original video.

@rlan
Copy link
Author

rlan commented Sep 12, 2023

@ankurbhatia24 No, I have not. Did you mean decoding video (eg mp4) into frames (eg jpg), instead?

@ankurbhatia24
Copy link

@rlan So my issue is:
I am using h264 codec and mp4 as container format.
Steps: 1. split video to 3 components: <1> - <2> -<3> using ffmpeg cut (-ss, -t)
2. write the frames from component 2 to disk using "ffmpeg -i {video_file}.mp4 -vf 'fps={video_fps},format=yuv420p' {out_folder}/{prefix}%d.png"
3. convert these frames to video using: "ffmpeg -f concat -safe 0 -i '{frames_txt_file}' -c:v libx264 -vf 'fps={frame_rate},format=yuv420p' '{output_video_path}'.mp4"
4. concat: <1> - <new 2> - <3>: will result in the middle component to be a little darker. shift is clearly visible?

@rlan
Copy link
Author

rlan commented Sep 12, 2023

@ankurbhatia24
Edit: sorry don't know why immediately. Just more questions:

  • What is the desired effect of 3? Is {frame_rate} different from {video_fps}?
  • Does png files from 2 look a little darker as in 4?

@ankurbhatia24
Copy link

@rlan the desired effect is to not have any visible color (luma/brightness) differences between the <1> <2> and <3> components. I am just writing frames from <2> to disk and re-encoding it again, it should not have changes in brightness.

@rlan
Copy link
Author

rlan commented Sep 13, 2023

@ankurbhatia24
Edit: read your link after writing below. What I suggested is what the person report as an issue. I guess I don't know.

My first bullet was asking what you want to do in the first place. It looks to me you want to modify just <2> of the video and not anywhere else. May be there is another road. For example, instead of concat, get all frames for the entire video, then make the modification to <2> frames, then assemble all frames back to a video.

@ankurbhatia24
Copy link

@rlan
My first bullet was asking what you want to do in the first place. It looks to me you want to modify just <2> of the video and not anywhere else. May be there is another road. For example, instead of concat, get all frames for the entire video, then make the modification to <2> frames, then assemble all frames back to a video.

So for this above, you are exactly right. I can write all frames, modify <2> and make a full video out of all frames. But here my question is that why is the color/luma difference happening and how can we solve that.

Lets simplify the problem: 1. take a video, 2. write the frames 3. read the frames to make it a video.
Now: the starting video and the new encoded video will have slight luma differences. I want to know why is this happening and how can i solve for this. I am not a ffmpeg pro so need help here. My gut feel is that while writing the frames (png) to disk colorspace conversion from yuv420p to rgb takes place and reverse happens when we encode the frames back to mp4. So is there some parameter which i am missing while encoding back, etc?

@rlan
Copy link
Author

rlan commented Sep 13, 2023

@ankurbhatia24 I see you want to understand the cause of the difference. I don't know the answer. In fact more questions come up in my head. Similar to you, I would start with color space of video vs images. Also I would have a rigorous way to measure luma difference, eg bits in files or some luma intensity definition. If you end up doing the analysis, I would be interested in the findings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment