Reputation: 3667
I am using ffmpeg
to record my outdoor camera video stream. The below script works pretty well to split the stream to be 1 hour video.
ffmpeg -nostdin -loglevel error -rtsp_transport tcp -i rtsp://username:[email protected]/stream1 -vcodec copy -acodec copy -f segment -reset_timestamps 1 -segment_time 3600 -segment_format mkv -segment_atclocktime 1 -strftime 1 ~/onedrive/camera/%Y%m%dT%H-%M-%S.mkv 2> ~/projects/ip-camera/upload.log
The only issue is the video file is too big, around 1GB for 1hour video file.
So I am trying to use libx265
to compress the video
ffmpeg -nostdin -loglevel error -rtsp_transport tcp -i rtsp://username:[email protected]/stream1 -c:v libx265 -crf 28 -acodec copy -f segment -reset_timestamps 1 -segment_time 3600 -segment_format mkv -segment_atclocktime 1 -strftime 1 ~/onedrive/camera/%Y%m%dT%H-%M-%S.mkv 2> ~/projects/ip-camera/upload.log
The strange thing is now ffmpeg
is generating random length video, between 5 minutes to 10 minutes for each video file.
What's wrong with my updated script? Couldn't ffmpeg
generate 1-hour length video just as before by initial script?
Upvotes: -1
Views: 176
Reputation:
The most common issue when dealing with segmentation and transcoding simultaneously is keyframes (or I-frames). When segmenting, ffmpeg
will ideally split the video at keyframes to avoid corruption or unplayable segments.
In your initial command, you used -vcodec copy
, which does a straight copy without transcoding. Therefore, the natural keyframe intervals from the source are retained, and ffmpeg
was probably segmenting on those keyframes that conveniently existed around the 1-hour mark.
However, when you introduced libx265
, the encoding process could introduce keyframes at different intervals than the source or your desired segmentation point.
To solve this:
Force keyframes: You can force keyframes at specific intervals, which can help in determining when to split the video. For example, to set keyframes every 10 seconds (assuming 30 fps), you'd use -force_key_frames "expr:gte(t,n_forced*10)"
. Adjust the 10
as needed based on your video's framerate.
Tune for zero-latency: Add -tune zerolatency
for real-time applications.
Preset: You might want to specify a preset. x265 has presets that determine the compression-speed trade-off. Slower presets will compress more (smaller output file) but will take longer. Common presets are ultrafast
, superfast
, veryfast
, faster
, fast
, medium
, slow
, slower
, veryslow
. The default is medium
. For faster encoding (at the expense of a slightly larger file size), you can try -preset fast
.
Combining these, your command would look something like:
ffmpeg -nostdin -loglevel error -rtsp_transport tcp -i rtsp://username:[email protected]/stream1 -c:v libx265 -crf 28 -preset fast -tune zerolatency -force_key_frames "expr:gte(t,n_forced*10)" -acodec copy -f segment -reset_timestamps 1 -segment_time 3600 -segment_format mkv -segment_atclocktime 1 -strftime 1 ~/onedrive/camera/%Y%m%dT%H-%M-%S.mkv 2> ~/projects/ip-camera/upload.log
Upvotes: 0