前言
1.寫作原因:iOS自己的播放器支持的格式有限,目前只有avi,mkv,mov,m4v,mp4等,像flv,rmvb等格式是不支持的,必須借助ffmpeg等第三方才能實(shí)現(xiàn)。
2.寫作目的:利用第三方ffmpeg完成對(duì)不支持格式的解碼和顯示,目前只針對(duì)視頻幀。
理論說明:
1.對(duì)于一個(gè)不能播放的視頻格式,我們的方法是先把他解碼成視頻幀,然后再以圖片的顯示一幀幀的顯示在屏幕上。
2.解碼:具體包括解復(fù)用,解碼和存儲(chǔ)流信息。
代碼實(shí)現(xiàn)(只關(guān)注解碼流程)
//注冊(cè)所有的文件格式和編解碼器
avcodec_register_all();
av_register_all();
//打開視頻文件,將文件格式的上下文傳遞到AVFormatContext類型的結(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;
}
//打開解碼器
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,便可以在屏幕上顯示出來了這里不再贅述,git代碼上有所體現(xiàn)。
代碼已經(jīng)傳到git上面
演示:

如果你覺得有用,就加個(gè)star吧??
注意:
** 1.代碼只做到了將視頻幀的解碼,并沒有涉及到音頻,因此不會(huì)有聲音出現(xiàn) **
** 2. 參考KXmovie**
** 3. ffmpeg的編譯已經(jīng)寫過一篇,不再贅述,使用時(shí)直接拖進(jìn)項(xiàng)目中即可,需要添加的依賴庫git上的項(xiàng)目也有所體現(xiàn)。**