Ich gründe das Format Layout für das Video wie folgt zusammen:FFmpeg „movflags“> „Fast Start“ bewirkt, dass ungültige MP4-Datei
AVOutputFormat* outputFormat = ffmpeg.av_guess_format(null, "output.mp4", null);
AVCodec* videoCodec = ffmpeg.avcodec_find_encoder(outputFormat->video_codec);
AVFormatContext* formatContext = ffmpeg.avformat_alloc_context();
formatContext->oformat = outputFormat;
formatContext->video_codec_id = videoCodec->id;
ffmpeg.avformat_new_stream(formatContext, videoCodec);
Dies ist, wie ich den Codec Kontext bin einrichten:
AVCodecContext* codecContext = ffmpeg.avcodec_alloc_context3(videoCodec);
codecContext->bit_rate = 400000;
codecContext->width = 1280;
codecContext->height = 720;
codecContext->gop_size = 12;
codecContext->max_b_frames = 1;
codecContext->pix_fmt = videoCodec->pix_fmts[0];
codecContext->codec_id = videoCodec->id;
codecContext->codec_type = videoCodec->type;
codecContext->time_base = new AVRational
{
num = 1,
den = 30
};
ich verwende den folgenden Code, um die "movflags" Setup> "Fast Start" Option für den Header des Videos:
AVDictionary* options = null;
int result = ffmpeg.av_dict_set(&options, "movflags", "faststart", 0);
int writeHeaderResult = ffmpeg.avformat_write_header(formatContext, &options);
Die Datei wird geöffnet und der Header wird wie folgt geschrieben:
if ((formatContext->oformat->flags & ffmpeg.AVFMT_NOFILE) == 0)
{
int ioOptionResult = ffmpeg.avio_open(&formatContext->pb, "output.mp4", ffmpeg.AVIO_FLAG_WRITE);
}
int writeHeaderResult = ffmpeg.avformat_write_header(formatContext, &options);
Danach habe ich jeden Video-Frame wie folgt schreiben:
outputFrame->pts = frameIndex;
packet.flags |= ffmpeg.AV_PKT_FLAG_KEY;
packet.pts = frameIndex;
packet.dts = frameIndex;
int encodedFrame = 0;
int encodeVideoResult = ffmpeg.avcodec_encode_video2(codecContext, &packet, outputFrame, &encodedFrame);
if (encodedFrame != 0)
{
packet.pts = ffmpeg.av_rescale_q(packet.pts, codecContext->time_base, m_videoStream->time_base);
packet.dts = ffmpeg.av_rescale_q(packet.dts, codecContext->time_base, m_videoStream->time_base);
packet.stream_index = m_videoStream->index;
if (codecContext->coded_frame->key_frame > 0)
{
packet.flags |= ffmpeg.AV_PKT_FLAG_KEY;
}
int writeFrameResult = ffmpeg.av_interleaved_write_frame(formatContext, &packet);
}
Danach schreibe ich den Trailer:
int writeTrailerResult = ffmpeg.av_write_trailer(formatContext);
Die Datei wird fertig geschrieben und alles wird geschlossen und freigegeben. Die MP4-Datei ist jedoch nicht abspielbar (selbst VLC kann sie nicht abspielen). AtomicParsley.exe zeigt auch keine Informationen über die Datei an.
Die DLLs für die AutoGen Bibliothek verwendet werden, sind:
avcodec-56.dll
avdevice-56.dll
avfilter-5.dll
avformat-56.dll
avutil-54.dll
postproc-53.dll
swresample-1.dll
swscale-3.dll
Wie erstellen Sie formatContext? – szatmary
Aktualisierte Frage. – williamtroup
Wo ist der io Kontext? Wo werden die Daten geschrieben? Wenn Sie ein Streaming-io (wie stout) verwenden, können Sie die Datei nicht schnell starten, da die Suche in einem Stream nicht funktioniert. – szatmary