Reputation: 36
I am using FFmpeg to create a mp4 file from screenshots and it works fine. But I want to flush the video to disk every 30 seconds so that in the case of program crash I don't lose everything. I tried to use avio_flush
method, but the problem is I have avformat_write_header(AVFormatContext* s)
methos at the initialization and if I don't close it using av_write_trailer(AVFormatContext* s)
it doesn't save the video correctly. If I close and reopen it, only the first portion gets saved (even if file size increases). I tried everything I could think of but I am stuck.
Update: Using the .h264 extension as suggested by @Nejat resolved the problem, but using this extension, I don't have the timestamps in the output video. Here is the part of my code to initialize packet pts and duration:
AV_TIME_BASE;
AVPacket pkt;
av_init_packet(&pkt);
pkt.data = nullptr;
pkt.size = 0;
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.pts -= first_pts;
pkt.duration = av_rescale_q(pkt.duration, cctx->time_base, stream->time_base);
pkt.pts = av_rescale_q(pkt.pts, cctx->time_base, stream->time_base);
pkt.dts = AV_NOPTS_VALUE;
if (avcodec_receive_packet(cctx, &pkt) == 0) {
static int counter = 0;
if (counter == 0) {
first_pts = pkt.pts;
pkt.pts = av_rescale_q(pkt.pts, cctx->time_base, stream->time_base);
}
if (av_interleaved_write_frame(ofctx, &pkt) < 0) {
fprintf(stderr, "Failed to write frame\n");
}
av_packet_unref(&pkt);
counter++;
}
Upvotes: 1
Views: 837
Reputation: 32645
For this use-case you could use MKV container instead of MP4. MKV does not need the av_write_trailer
to be called for being valid. When you record on MKV containers, you could watch the video on the fly while the file is still open and you are writing to it. So in case of a crash you don't miss anything that has been written to video file.
Upvotes: 1