I have a h264 encoded mp4 video of about 27.5 minutes length and I am trying to create a copy of the video which excludes the first 5 frames. I am using scikit-video and ffmpeg in python for this purpose. I do not have a GPU, so I am using libx264 codec for the output video.
It generally works and the output video excludes the first 5 frames. Somehow, the output video results in a length of about 22 minutes. When visually checking the videos, the shorter video does seem slightly faster and I can identify the same frames at different timestamps. In windows explorer, when clicking properties and then details, both videos’ frame rates show as 20.00 fps.
Another small problem I noticed, is that the output video seems to have slightly less good quality.
Furthermore it would be helpful if someone knows a where to find all the right names of the parameters or how to give them into the output_dict.
So, my goal is to have both videos of the same length, except for the loss of the first 5 frames which should result in a duration difference of 0.25 seconds, and use the same (almost same) codec and not lose quality.
Thank you for your interest in helping me, please find the details below.
Here is a minimal example of what I have done.
framerate = str(20)
reader = skvideo.io.FFmpegReader(inputvideo.mp4, inputdict={'-r': framerate})
writer = skvideo.io.FFmpegWriter(outputvideo.mp4, outputdict={'-vcodec': 'libx264', '-r': framerate})
for idx,frame in enumerate(reader.nextFrame()):
if idx < 5:
continue
writer.writeFrame(frame)
reader.close()
writer.close()
When I read the output video again using FFmpegReader and check the .probeInfo, I can see that the output video has less frames in total. I have also managed to replicate the same problem for shorter videos (now not excluding the first 5 frames, but only throughputting a video), e.g. 10 seconds input turns to 8 seconds output with less frames. I have also tried playing around with further parameters of the outputdict, e.g. -pix_fmt, -b. I have tried to set -time_base in the output dict to the same value as in the inputdict, but that did not seem to have the desired effect. I am not sure if the name of the right parameter is right.
For additional info, I am providing the .probeInfo of the input video, of which I used 10 seconds, and the .probeInfo of the 8 second output video it produced.
**input video** .probeInfo:
input dict
{'video': OrderedDict([('@index', '0'),
('@codec_name', 'h264'),
('@codec_long_name',
'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10'),
('@profile', 'High 4:4:4 Predictive'),
('@codec_type', 'video'),
('@codec_tag_string', 'avc1'),
('@codec_tag', '0x31637661'),
('@width', '4096'),
('@height', '3000'),
('@coded_width', '4096'),
('@coded_height', '3000'),
('@closed_captions', '0'),
('@film_grain', '0'),
('@has_b_frames', '0'),
('@sample_aspect_ratio', '1:1'),
('@display_aspect_ratio', '512:375'),
('@pix_fmt', 'yuv420p'),
('@level', '60'),
('@chroma_location', 'left'),
('@field_order', 'progressive'),
('@refs', '1'),
('@is_avc', 'true'),
('@nal_length_size', '4'),
('@id', '0x1'),
('@r_frame_rate', '20/1'),
('@avg_frame_rate', '20/1'),
('@time_base', '1/1200000'),
('@start_pts', '0'),
('@start_time', '0.000000'),
('@duration_ts', '1984740000'),
('@duration', '1653.950000'),
('@bit_rate', '3788971'),
('@bits_per_raw_sample', '8'),
('@nb_frames', '33079'),
('@extradata_size', '43'),
('disposition',
OrderedDict([('@default', '1'),
('@dub', '0'),
('@original', '0'),
('@comment', '0'),
('@lyrics', '0'),
('@karaoke', '0'),
('@forced', '0'),
('@hearing_impaired', '0'),
('@visual_impaired', '0'),
('@clean_effects', '0'),
('@attached_pic', '0'),
('@timed_thumbnails', '0'),
('@non_diegetic', '0'),
('@captions', '0'),
('@descriptions', '0'),
('@metadata', '0'),
('@dependent', '0'),
('@still_image', '0')])),
('tags',
OrderedDict([('tag',
[OrderedDict([('@key', 'language'),
('@value', 'und')]),
OrderedDict([('@key', 'handler_name'),
('@value', 'VideoHandler')]),
OrderedDict([('@key', 'vendor_id'),
('@value', '[0][0][0][0]')])])]))])}
**output video** .probeInfo:
{'video': OrderedDict([('@index', '0'),
('@codec_name', 'h264'),
('@codec_long_name',
'H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10'),
('@profile', 'High'),
('@codec_type', 'video'),
('@codec_tag_string', 'avc1'),
('@codec_tag', '0x31637661'),
('@width', '4096'),
('@height', '3000'),
('@coded_width', '4096'),
('@coded_height', '3000'),
('@closed_captions', '0'),
('@film_grain', '0'),
('@has_b_frames', '2'),
('@pix_fmt', 'yuv420p'),
('@level', '60'),
('@chroma_location', 'left'),
('@field_order', 'progressive'),
('@refs', '1'),
('@is_avc', 'true'),
('@nal_length_size', '4'),
('@id', '0x1'),
('@r_frame_rate', '20/1'),
('@avg_frame_rate', '20/1'),
('@time_base', '1/10240'),
('@start_pts', '0'),
('@start_time', '0.000000'),
('@duration_ts', '82944'),
('@duration', '8.100000'),
('@bit_rate', '3444755'),
('@bits_per_raw_sample', '8'),
('@nb_frames', '162'),
('@extradata_size', '47'),
('disposition',
OrderedDict([('@default', '1'),
('@dub', '0'),
('@original', '0'),
('@comment', '0'),
('@lyrics', '0'),
('@karaoke', '0'),
('@forced', '0'),
('@hearing_impaired', '0'),
('@visual_impaired', '0'),
('@clean_effects', '0'),
('@attached_pic', '0'),
('@timed_thumbnails', '0'),
('@non_diegetic', '0'),
('@captions', '0'),
('@descriptions', '0'),
('@metadata', '0'),
('@dependent', '0'),
('@still_image', '0')])),
('tags',
OrderedDict([('tag',
[OrderedDict([('@key', 'language'),
('@value', 'und')]),
OrderedDict([('@key', 'handler_name'),
('@value', 'VideoHandler')]),
OrderedDict([('@key', 'vendor_id'),
('@value', '[0][0][0][0]')]),
OrderedDict([('@key', 'encoder'),
('@value',
'Lavc61.8.100 libx264')])])]))])}
I used 10 seconds by adding this to the bottom of the loop shown above:
if idx >= 200:
break
Kaesebrotus Anonymous is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.