मैंने ffmpeg का उपयोग शुरू किया और मैं avi फ़ाइल को mp4/h264 फ़ाइल में कनवर्ट करना चाहता हूं। मैंने this समेत कई पोस्ट पढ़ी हैं, लेकिन मुझे कोई अच्छा उदाहरण नहीं मिला कि फ्रेम को mp4 फ़ाइल में कैसे सहेजना है। नीचे दिया गया कोड सरलीकृत है जो एवीआई फ़ाइल से फ्रेम को डीकोड करता है और इसे H264/mp4 फ़ाइल में एन्कोड करता है, लेकिन जब मैं फ्रेम को सहेजता हूं तो mp4 फ़ाइल नहीं खेला जा सकता है। मुझे लगता है कि मैं एन्कोडिंगएवी कंटेनर से फ़्रेम को डीकोड करना और उन्हें h264/mp4 में एन्कोड क्यों नहीं करता है?
में कुछ गड़बड़ कर दूंगा यदि आप मुझे बता सकते हैं कि क्या गलत है और इसे कैसे ठीक किया जाए।
const char* aviFileName = "aviFrom.avi";
const char* mp4FileName = "mp4To.mp4";
// Filling pFormatCtx by open video file and Retrieve stream information
// ...
// Retrieving codecCtxDecode and opening codecDecode
//...
// Get encoder
codecCtxEncode = avcodec_alloc_context();
codecCtxEncode->qmax = 69;
codecCtxEncode->max_qdiff = 4;
codecCtxEncode->bit_rate = 400000;
codecCtxEncode->width = codecCtxDecode->width;
codecCtxEncode->height = codecCtxDecode->height;
codecCtxEncode->pix_fmt = AV_PIX_FMT_YUV420P;
codecEncode = avcodec_find_encoder(CODEC_ID_H264);
if(codecEncode == NULL)
return -1;
if(avcodec_open2(codecCtxEncode, codecEncode, NULL))
return -1;
SwsContext *sws_ctx = sws_getContext(codecCtxDecode->width, codecCtxDecode->height, codecCtxDecode->pix_fmt,
codecCtxDecode->width, codecCtxDecode->height, AV_PIX_FMT_YUV420P,
SWS_BILINEAR, NULL, NULL, NULL);
// Allocate an AVFrame structure
frameDecoded = avcodec_alloc_frame();
frameEncoded = avcodec_alloc_frame();
avpicture_alloc((AVPicture *)frameEncoded, AV_PIX_FMT_YUV420P, codecCtxDecode->width, codecCtxDecode->height);
while(av_read_frame(pFormatCtx, &packet)>=0)
{
// Is this a packet from the video stream?
if(packet.stream_index==videoStreamIndex) {
avcodec_decode_video2(codecCtxDecode, frameDecoded, &frameFinished, &packet);
// Did we get a video frame?
if(frameFinished)
{
fwrite(packet.data, packet.size,
sws_scale(sws_ctx, frameDecoded->data, frameDecoded->linesize, 0, codecCtxDecode->height,
frameEncoded->data, frameEncoded->linesize);
int64_t pts = packet.pts;
av_free_packet(&packet);
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;
frameEncoded->pts = pts;
int failed = avcodec_encode_video2(codecCtxEncode, &packet, frameEncoded, &got_output);
if(failed)
{
exit(1);
}
fwrite(packet.data,1,packet.size, mp4File);
}
}
av_free_packet(&packet);
}
hypothetically, अगर मैं मैन्युअल रूप से होगा फ़ाइल में हेडर और पाद लेख जोड़ें, क्या यह ठीक होगा? – theateist
कुछ प्रारूपों के लिए, यह काम कर सकता है, लेकिन सामान्य रूप से, यह गलत तरीका है। – pogorskiy
आपके द्वारा लिखे गए प्रयोग के प्रयोग के रूप में मैंने एवीआई फ़ाइल से पढ़ने की कोशिश की और नई एवी फ़ाइल में मैंने जो पैकेट पढ़ा है (डीकोडिंग के बिना) लिखा है। मुझे एक ही फाइल प्राप्त करने की उम्मीद है लेकिन नई फाइल 3KB पर बड़ी है और मीडिया प्लेयर इसे – theateist