1. 程式人生 > >XCode版【100行程式碼實現最簡單的基於FFMPEG+SDL的視訊播放器】

XCode版【100行程式碼實現最簡單的基於FFMPEG+SDL的視訊播放器】

【來自】

1.新建XCode工程後,發現即使安裝了SDL和FFMPEG也編譯不成功,需要修改各種環境。經過我的不懈努力加百穀啥的...貼個能編譯通過的過程出來。謹記!

2.首先需要編譯好ffmpeg原始碼,然後還需要安裝SDL(ffmpeg直接編譯,SDL我是通過brew安裝的)

3.修改工程的搜尋路徑,Header search Path新增ffmpeg的include目錄以及/usr/local/include目錄,告知Xcode需要使用的FFMPEG以及SDL標頭檔案的路徑,Library search path則是對應的FFMPEG以及SDL的庫目錄

4.新增其他引用庫以及框架,如下圖所示:


5.基本不用改的程式碼如下:

/**
 * 最簡單的基於FFmpeg的視訊播放器
 * Simplest FFmpeg Player
 *
 * 雷霄驊 Lei Xiaohua
 * [email protected]
 * 中國傳媒大學/數字電視技術
 * Communication University of China / Digital TV Technology
 * http://blog.csdn.net/leixiaohua1020
 *
 * 本程式實現了視訊檔案的解碼和顯示(支援HEVC,H.264,MPEG2等)。
 * 是最簡單的FFmpeg視訊解碼方面的教程。
 * 通過學習本例子可以瞭解FFmpeg的解碼流程。
 * This software is a simplest video player based on FFmpeg.
 * Suitable for beginner of FFmpeg.
 *
 * Version:1.0
 */


extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "sdl/SDL.h"
#include "sdl/SDL_thread.h"
};

//Full Screen
#define SHOW_FULLSCREEN 0
//Output YUV420P
#define OUTPUT_YUV420P 0

int main(int argc, char* argv[])
{
    
    AVFormatContext	*pFormatCtx;
    int				i, videoindex;
    AVCodecContext	*pCodecCtx;
    AVCodec			*pCodec;
    char filepath[]="/Users/wangwei/src/1.mkv";
    av_register_all();
    avformat_network_init();
    pFormatCtx = avformat_alloc_context();
    
    if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){
        printf("Couldn't open input stream.(無法開啟輸入流)\n");
        return -1;
    }
    if(avformat_find_stream_info(pFormatCtx, NULL) < 0)
    {
        printf("Couldn't find stream information.(無法獲取流資訊)\n");
        return -1;
    }
    videoindex=-1;
    for(i=0; i<pFormatCtx->nb_streams; i++)
        if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
        {
            videoindex=i;
            break;
        }
    if(videoindex==-1)
    {
        printf("Didn't find a video stream.(沒有找到視訊流)\n");
        return -1;
    }
    pCodecCtx=pFormatCtx->streams[videoindex]->codec;
    pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
    if(pCodec==NULL)
    {
        printf("Codec not found.(沒有找到解碼器)\n");
        return -1;
    }
    if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
    {
        printf("Could not open codec.(無法開啟解碼器)\n");
        return -1;
    }
    AVFrame	*pFrame,*pFrameYUV;
    pFrame=avcodec_alloc_frame();
    pFrameYUV=avcodec_alloc_frame();
    uint8_t *out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
    avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
    //------------SDL----------------
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
        printf( "Could not initialize SDL - %s\n", SDL_GetError());
        return -1;
    }
    
    int screen_w=0,screen_h=0;
    SDL_Surface *screen;
#if SHOW_FULLSCREEN
    const SDL_VideoInfo *vi = SDL_GetVideoInfo();
    screen_w = vi->current_w;
    screen_h = vi->current_h;
    screen = SDL_SetVideoMode(screen_w, screen_h, 0,SDL_FULLSCREEN);
#else
    screen_w = pCodecCtx->width;
    screen_h = pCodecCtx->height;
    screen = SDL_SetVideoMode(screen_w, screen_h, 0,0);
#endif
    
    if(!screen) {
        printf("SDL: could not set video mode - exiting:%s\n",SDL_GetError());
        return -1;
    }
    SDL_Overlay *bmp;
    bmp = SDL_CreateYUVOverlay(pCodecCtx->width, pCodecCtx->height,SDL_YV12_OVERLAY, screen);
    SDL_Rect rect;
    
    int ret, got_picture;
    
    AVPacket *packet=(AVPacket *)av_malloc(sizeof(AVPacket));
    //輸出一下資訊-----------------------------
    printf("File Information(檔案資訊)---------------------\n");
    av_dump_format(pFormatCtx,0,filepath,0);
    printf("-------------------------------------------------\n");
    
#if OUTPUT_YUV420P
    FILE *fp_yuv=fopen("output.yuv","wb+");
#endif
    
    
    struct SwsContext *img_convert_ctx;
    img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
    //------------------------------
    while(av_read_frame(pFormatCtx, packet)>=0)
    {
        if(packet->stream_index==videoindex)
        {
            ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
            if(ret < 0)
            {
                printf("Decode Error.(解碼錯誤)\n");
                return -1;
            }
            if(got_picture)
            {
                sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
                
#if OUTPUT_YUV420P
                int y_size=pCodecCtx->width*pCodecCtx->height;
                fwrite(pFrameYUV->data[0],1,y_size,fp_yuv);    //Y
                fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv);  //U
                fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv);  //V
#endif
                SDL_LockYUVOverlay(bmp);
                bmp->pixels[0]=pFrameYUV->data[0];
                bmp->pixels[2]=pFrameYUV->data[1];
                bmp->pixels[1]=pFrameYUV->data[2];
                bmp->pitches[0]=pFrameYUV->linesize[0];
                bmp->pitches[2]=pFrameYUV->linesize[1];
                bmp->pitches[1]=pFrameYUV->linesize[2];
                SDL_UnlockYUVOverlay(bmp); 
                rect.x = 0;    
                rect.y = 0;    
                rect.w = screen_w;    
                rect.h = screen_h;  
                //測試自己填充資料----------------
                SDL_DisplayYUVOverlay(bmp, &rect); 
                //延時40ms
                //SDL_Delay(40);
            }
        }
        av_free_packet(packet);
    }
    sws_freeContext(img_convert_ctx);
    
#if OUTPUT_YUV420P 
    fclose(fp_yuv);
#endif 
    
    SDL_Quit();
    
    av_free(out_buffer);
    av_free(pFrameYUV);
    avcodec_close(pCodecCtx);
    avformat_close_input(&pFormatCtx);
    
    return 0;
}
6.我反正編譯通過了,可以播放視訊,不過木有聲音

相關推薦

XCode100程式碼實現簡單基於FFMPEG+SDL視訊播放

【來自】 1.新建XCode工程後,發現即使安裝了SDL和FFMPEG也編譯不成功,需要修改各種環境。經過我的不懈努力加百穀啥的...貼個能編譯通過的過程出來。謹記! 2.首先需要編譯好ffmpeg原始碼,然後還需要安裝SDL(ffmpeg直接編譯,SDL我是通過brew安

100程式碼實現簡單基於FFMPEG+SDL視訊播放(SDL1.x)

                =====================================================最簡單的基於FFmpeg的視訊播放器系列文章列表:=====================================================簡介FFMPEG

不到100程式碼實現一個簡單的推薦系統

一個好的推薦系統推薦的精度必然很高,能夠真的發現使用者的潛在需求或喜好,提高購物網詀的銷量,讓視訊網站發現使用者喜歡的收費電影… 可是要實現一個高精度的推薦系統不是那麼容易的,netflix曾經懸賞高額獎金尋找能給其推薦系統的精確度提高10%的人,可見各個公司對推薦系統的

UI視覺100程式碼實現微信底部漸變切換效果!!!

1、我們先來看一下要實現的效果 2、我們看到當進行切換頁面的時候,關聯的兩個Tab將會產生過渡效果,接下來我們用最簡單的程式碼去實現 3、思路:在Tab上放置一張為選中時的圖片,再將已經選中的圖片覆蓋在未選中的圖片上,我們來控制選中圖片的透明度來實現漸變。 4、佈局方面:這是單個T

100程式碼實現一個vue分頁元件

今天用vue來實現一個分頁元件,總體來說,vue實現比較簡單,樣式部分模仿了elementUI。所有程式碼的原始碼可以再github上下載的到:下載地址 先來看一下實現效果: 點選檢視效果 整體思路 我們先看一下使用到的檔案的目錄: 我們在 pageComponentsTe

100程式碼 實現 釘釘實現自動打卡

越有錢的公司越不會在意這些打卡的字面東西,也不會讓你天天寫個日報啥的。不寫還罰錢 遲到還扣錢。 emmm… 當一個公司開始計較這些東西的時候 ,他就開始走下坡路了。廢話不多說。開始走起我們程式設計師的翻盤之路 程式碼 下載地址 掃碼或安裝包下載

簡單基於libVLC的例子:簡單基於libVLC的視訊播放(圖形介面

=====================================================最簡單的基於libVLC的例子文章列表:=====================================================本文記錄使用libVLC

基於 ffmpeg 的跨平臺播放實現

空間 編解碼 流程 position eat clu ict 網絡協議 紋理貼圖 https://www.qcloud.com/community/article/309889001486708756 背景: 隨著遊戲娛樂等直播業務的增長,在移動端觀看直播的需求也日益迫切。

Unity 2d/3d視訊播放

https://github.com/86K/2D3D_VideoPlayer Unity2017.3.1f1 3d部分是htc硬體對接的。 視訊播放、暫停;聲音、速度調節;選集等功能都已實現。 主要參照htc官方視訊播放器模式。 原先的

原創關於視訊播放如何做到邊播邊快取?如何用Vitamio做一款功能強大的視訊播放補充篇

上一篇介紹了怎樣做一款功能強大的視訊播放器,是基於Vitamio框架開發的。這裡我們再補充一個功能:如何做到視訊邊播放邊快取到本地? 這個需求還挺常見的。由於使用者的網路環境複雜,經常會有網速較慢看視訊時卡頓、緩衝的現象,並且有時候我們需要頻繁的拖拽進度條,如果播放的是

簡單基於FFMPEG視訊編碼(YUV編碼為H.264)

                =====================================================最簡單的基於FFmpeg的視訊編碼器文章列表:=====================================================本文介紹一個最簡單的

視訊播放potplayer調教教程

Potplayer基礎調教教程 一、設定相關 1.0 基本 最前端方式:不使用最前端功能 這個就是設定介面是否總在最前,全屏時狀態列不自動隱藏不建議在這裡設定 相似檔案策略:同時開啟全部檔案 即開啟一個檔案時把同文件夾下的其他支援的檔案也新增到播放列

[轉載]分享10款棒的免費HTML5視訊播放

最近Web圈子裡最讓人激動地莫過於HTML5了,特別是HTML5視訊,使用HTML5視訊標籤可以幫助我們解決困擾我們很長時間的網站視訊插入問題。 HTML5可以在沒有flash的情況下播放視訊。現在有很多的漂亮HTML5視訊播放介面,包括控制元素,所以你不需要其它的東

簡單基於libVLC的例子:簡單基於libVLC的視訊播放

=====================================================最簡單的基於libVLC的例子文章列表:=====================================================本文記錄使用libVLC

100代碼實現簡單基於FFMPEG+SDL的視頻播放(SDL1.x)

工程 全屏 升級版 gin avcodec ive 系列文章 相同 hello 轉自:http://blog.csdn.net/leixiaohua1020/article/details/8652605 版權聲明:本文為博主原創文章,未經博主允許不得轉載。

程式碼實現微信多開(電腦

轉自:http://www.hurbai.com 首先在桌面建立一個 .bat檔案,我這裡命名 微信多開.bat 然後將 微信多開.bat 檔案用Notepad++或者記事本開啟將以下兩行程式碼複製貼上過去儲存即可實現多開的效果。 PATH C:\Program Files (x8

年薪60萬的程式設計師有多強?canvas雨滴特效100程式碼輕鬆實現

今天小編我逛論壇,看到了一位大佬程式設計師面試滴滴出行的經歷,小夥是應屆畢業生,也在我群裡,今年剛畢業就去了滴滴出行面試一下,前面幾場面試都很輕鬆,最後一場面試官想靠他的開發能力,於是小夥就徒手開發除了這個煙花特效,也是挺厲害的,小編我把程式碼也COPY了一份,獻給頭條上的小

程式碼實現微信電腦多開

兩行程式碼實現的微信電腦版多開 首先在桌面建立一個 .bat檔案,我這裡命名 微信多開.bat 然後將 微信多開.bat 檔案用Notepad++或者記事本開啟將以下兩行程式碼複製貼上過去儲存即可實現多開的效果。 PATH C:\Program

Android程式碼實現一個輪播BannerView

自己簡單封裝了一個帶hint的輪播ViewPager,用來展示app首頁的Banner,先看效果圖吧。 ezgif-1-437f7aee24.gif dependencies(依賴) compile 'com.coldmoqiuli:banners:1.0.0'

LSTM實現股票預測--pytorch版本120+程式碼

簡述 網上看到有人用Tensorflow寫了的但是沒看到有用pytorch寫的。 所以我就寫了一份。寫的過程中沒有參照任何TensorFlow版本的(因為我對TensorFlow目前理解有限),所以寫得比較簡單,看來來似乎也比較容易實現(歡迎各位大佬改進之後,發家致富,帶帶小弟hhh