前言
1.寫(xiě)作原因:iOS自己的播放器支持的格式有限拴签,目前只有avi,mkv,mov,m4v,mp4等旗们,像flv上渴,rmvb等格式是不支持的,必須借助ffmpeg等第三方才能實(shí)現(xiàn)盛嘿。
2.寫(xiě)作目的:利用第三方ffmpeg完成對(duì)不支持格式的解碼和顯示括袒,目前只針對(duì)視頻幀。
理論說(shuō)明:
1.對(duì)于一個(gè)不能播放的視頻格式芥炭,我們的方法是先把他解碼成視頻幀园蝠,然后再以圖片的顯示一幀幀的顯示在屏幕上痢士。
2.解碼:具體包括解復(fù)用,解碼和存儲(chǔ)流信息善延。
代碼實(shí)現(xiàn)(只關(guān)注解碼流程)
//注冊(cè)所有的文件格式和編解碼器
avcodec_register_all();
av_register_all();
//打開(kāi)視頻文件,將文件格式的上下文傳遞到AVFormatContext類(lèi)型的結(jié)構(gòu)體中
if (avformat_open_input(&pFormatContext, [moviePath cStringUsingEncoding:NSASCIIStringEncoding], NULL, NULL)) {
av_log(NULL, AV_LOG_ERROR, "Couldn't open file\n");
goto initError;
}
//查找文件中視頻流的信息
if (avformat_find_stream_info(pFormatContext, NULL) < 0) {
av_log(NULL, AV_LOG_ERROR, "Couldn't find a video stream in the input");
goto initError;
}
//find the first video stream
if ((videoStream = av_find_best_stream(pFormatContext, AVMEDIA_TYPE_VIDEO, -1, -1, &pCodec, 0)) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot find a video stream in the input file\n");
goto initError;
}
//
pCodecContext = pFormatContext->streams[videoStream]->codec;
//找到該視頻流對(duì)應(yīng)的解碼器
pCodec = avcodec_find_decoder(pCodecContext->codec_id);
if (pCodec == NULL) {
av_log(NULL, AV_LOG_ERROR, "Unsupported codec!\n");
goto initError;
}
//打開(kāi)解碼器
if (avcodec_open2(pCodecContext, pCodec, NULL) < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot open video decoder\n");
goto initError;
}
pFrame = av_frame_alloc();
_outputWidth = pCodecContext->width;
self.outputHeight = pCodecContext->height;
后面就是將YUV數(shù)據(jù)轉(zhuǎn)換為RGB易遣,然后將RGB圖像轉(zhuǎn)換為UIImage豆茫,便可以在屏幕上顯示出來(lái)了這里不再贅述屋摇,git代碼上有所體現(xiàn)。
代碼已經(jīng)傳到git上面
演示:
如果你覺(jué)得有用火脉,就加個(gè)star吧??
注意:
** 1.代碼只做到了將視頻幀的解碼忘分,并沒(méi)有涉及到音頻,因此不會(huì)有聲音出現(xiàn) **
** 2. 參考KXmovie**
** 3. ffmpeg的編譯已經(jīng)寫(xiě)過(guò)一篇重斑,不再贅述肯骇,使用時(shí)直接拖進(jìn)項(xiàng)目中即可,需要添加的依賴(lài)庫(kù)git上的項(xiàng)目也有所體現(xiàn)笛丙。**