Reputation: 1
I have an 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.
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.
Can anyone explain why this apparent loss of frames is happening?
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 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
Upvotes: 0
Views: 120