【Android FFMPEG 开发】FFMPEG 初始化 ( 网络初始化 | 打开音视频 | 查找音视频流 )
文章目錄
- I . FFMPEG 初始化流程
- II . FFMPEG 網絡初始化 avformat_network_init()
- III . FFMPEG 打開媒體地址 avformat_open_input()
- IV . FFMPEG 獲取音 / 視頻流信息 avformat_find_stream_info()
- V . FFMPEG 初始化部分代碼示例
I . FFMPEG 初始化流程
FFMPEG 初始化流程 : FFMPEG 執行任何操作前 , 都需要初始化一些環境 , 及相關數據參數 ;
① 網絡初始化 : avformat_network_init()
int avformat_network_init(void);② 打開媒體 ( 音視頻 ) 地址 : avformat_open_input()
int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);③ 查找 ( 音 / 視頻 ) 流 : avformat_find_stream_info()
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);④ 正式操作 : 對上述查找到的 音 / 視頻 流進行操作 ;
II . FFMPEG 網絡初始化 avformat_network_init()
調用 avformat_network_init() 函數進行網絡初始化
1 . avformat_network_init() 函數作用 : 初始化網絡 , 默認狀態下 , FFMPEG 是不允許聯網的 , 必須調用該函數 , 初始化網絡后 FFMPEG 才能進行聯網 ;
2 . avformat_network_init() 函數原型 :
/*** Do global initialization of network libraries. This is optional,* and not recommended anymore.** This functions only exists to work around thread-safety issues* with older GnuTLS or OpenSSL libraries. If libavformat is linked* to newer versions of those libraries, or if you do not use them,* calling this function is unnecessary. Otherwise, you need to call* this function before any other threads using them are started.** This function will be deprecated once support for older GnuTLS and* OpenSSL libraries is removed, and this function has no purpose* anymore.*/ int avformat_network_init(void);3 . 使用示例 :
/** 初始化網絡 :* 默認狀態下 , FFMPEG 是不允許聯網的* 必須調用該函數 , 初始化網絡后 FFMPEG 才能進行聯網*/avformat_network_init();III . FFMPEG 打開媒體地址 avformat_open_input()
調用 avformat_open_input() 函數打開音視頻地址 ( 文件地址 / 網絡地址 )
1 . avformat_open_input() 函數作用 : 播放一個音視頻多媒體文件之前 , 首先要打開該文件 ; 文件的地址類型可以是文件路徑地址 , 也可以是網絡地址 ;
2 . avformat_open_input() 函數原型 :
① AVFormatContext **ps 參數 : 封裝了文件格式相關信息的結構體 , 如視頻寬高 , 音頻采樣率等信息 ; 該參數是 二級指針 , 意味著在方法中會修改該指針的指向 , 該參數的實際作用是當做返回值用的 ;
② const char *url 參數 : 視頻資源地址, 文件地址 / 網絡鏈接 ;
③ int 返回值 : 返回 0 , 代表打開成功 , 否則失敗 ; 失敗的情況列舉 , 文件路徑錯誤 , 網絡錯誤 ;
/*** Open an input stream and read the header. The codecs are not opened.* The stream must be closed with avformat_close_input().** @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context).* May be a pointer to NULL, in which case an AVFormatContext is allocated by this* function and written into ps.* Note that a user-supplied AVFormatContext will be freed on failure.* @param url URL of the stream to open.* @param fmt If non-NULL, this parameter forces a specific input format.* Otherwise the format is autodetected.* @param options A dictionary filled with AVFormatContext and demuxer-private options.* On return this parameter will be destroyed and replaced with a dict containing* options that were not found. May be NULL.** @return 0 on success, a negative AVERROR on failure.** @note If you want to use custom IO, preallocate the format context and set its pb field.*/ int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);3 . 使用示例 :
//1 . 打開音視頻地址 ( 播放文件前 , 需要先將文件打開 )// 地址類型 : ① 文件類型 , ② 音視頻流// 參數解析 :// AVFormatContext **ps : 封裝了文件格式相關信息的結構體 , 如視頻寬高 , 音頻采樣率等信息 ;// 該參數是 二級指針 , 意味著在方法中會修改該指針的指向 ,// 該參數的實際作用是當做返回值用的// const char *url : 視頻資源地址, 文件地址 / 網絡鏈接// 返回值說明 : 返回 0 , 代表打開成功 , 否則失敗// 失敗的情況 : 文件路徑錯誤 , 網絡錯誤//int avformat_open_input(AVFormatContext **ps, const char *url,// AVInputFormat *fmt, AVDictionary **options);formatContext = 0;int open_result = avformat_open_input(&formatContext, dataSource, 0, 0);//如果返回值不是 0 , 說明打開視頻文件失敗 , 需要將錯誤信息在 Java 層進行提示// 這里將錯誤碼返回到 Java 層顯示即可if(open_result != 0){__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "打開媒體失敗 : %s", av_err2str(open_result));callHelper->onError(pid, 0);}IV . FFMPEG 獲取音 / 視頻流信息 avformat_find_stream_info()
調用 avformat_find_stream_info() 函數獲取音視頻流信息
1 . avformat_find_stream_info() 函數作用 : 打開音視頻文件成功后 , 從該地址中獲取對應的音視頻流 , 獲取的流賦值給了 AVFormatContext* 結構體的 nb_streams 成員 ;
2 . avformat_find_stream_info() 函數原型 :
① AVFormatContext **ps 參數 : 封裝了文件格式相關信息的結構體 , 如視頻寬高 , 音頻采樣率等信息 ; 該參數是 二級指針 , 意味著在方法中會修改該指針的指向 , 該參數的實際作用是當做返回值用的 ;
調用該方法后 , AVFormatContext 結構體的 nb_streams 元素就有值了 ;
③ int 返回值 : 返回值 >= 0 , 代表打開成功 , 否則失敗 ;
/*** Read packets of a media file to get stream information. This* is useful for file formats with no headers such as MPEG. This* function also computes the real framerate in case of MPEG-2 repeat* frame mode.* The logical file position is not changed by this function;* examined packets may be buffered for later processing.** @param ic media file handle* @param options If non-NULL, an ic.nb_streams long array of pointers to* dictionaries, where i-th member contains options for* codec corresponding to i-th stream.* On return each dictionary will be filled with options that were not found.* @return >=0 if OK, AVERROR_xxx on error** @note this function isn't guaranteed to open all the codecs, so* options being non-empty at return is a perfectly normal behavior.** @todo Let the user decide somehow what information is needed so that* we do not waste time getting stuff the user does not need.*/ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);3 . 使用示例 :
//2 . 查找媒體 地址 對應的音視頻流 ( 給 AVFormatContext* 成員賦值 )// 方法原型 : int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);// 調用該方法后 , AVFormatContext 結構體的 nb_streams 元素就有值了 ,// 該值代表了音視頻流 AVStream 個數int find_result = avformat_find_stream_info(formatContext, 0);//如果返回值 < 0 , 說明查找音視頻流失敗 , 需要將錯誤信息在 Java 層進行提示// 這里將錯誤碼返回到 Java 層顯示即可if(find_result < 0){__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "查找媒體流失敗 : %s", av_err2str(find_result));callHelper->onError(pid, 1);}V . FFMPEG 初始化部分代碼示例
/** 初始化網絡 :* 默認狀態下 , FFMPEG 是不允許聯網的* 必須調用該函數 , 初始化網絡后 FFMPEG 才能進行聯網*/avformat_network_init();//0 . 注冊組件// 如果是 4.x 之前的版本需要執行該步驟// 4.x 及之后的版本 , 就沒有該步驟了//av_register_all();//1 . 打開音視頻地址 ( 播放文件前 , 需要先將文件打開 )// 地址類型 : ① 文件類型 , ② 音視頻流// 參數解析 :// AVFormatContext **ps : 封裝了文件格式相關信息的結構體 , 如視頻寬高 , 音頻采樣率等信息 ;// 該參數是 二級指針 , 意味著在方法中會修改該指針的指向 ,// 該參數的實際作用是當做返回值用的// const char *url : 視頻資源地址, 文件地址 / 網絡鏈接// 返回值說明 : 返回 0 , 代表打開成功 , 否則失敗// 失敗的情況 : 文件路徑錯誤 , 網絡錯誤//int avformat_open_input(AVFormatContext **ps, const char *url,// AVInputFormat *fmt, AVDictionary **options);formatContext = 0;int open_result = avformat_open_input(&formatContext, dataSource, 0, 0);//如果返回值不是 0 , 說明打開視頻文件失敗 , 需要將錯誤信息在 Java 層進行提示// 這里將錯誤碼返回到 Java 層顯示即可if(open_result != 0){__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "打開媒體失敗 : %s", av_err2str(open_result));callHelper->onError(pid, 0);}//2 . 查找媒體 地址 對應的音視頻流 ( 給 AVFormatContext* 成員賦值 )// 方法原型 : int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);// 調用該方法后 , AVFormatContext 結構體的 nb_streams 元素就有值了 ,// 該值代表了音視頻流 AVStream 個數int find_result = avformat_find_stream_info(formatContext, 0);//如果返回值 < 0 , 說明查找音視頻流失敗 , 需要將錯誤信息在 Java 層進行提示// 這里將錯誤碼返回到 Java 層顯示即可if(find_result < 0){__android_log_print(ANDROID_LOG_ERROR , "FFMPEG" , "查找媒體流失敗 : %s", av_err2str(find_result));callHelper->onError(pid, 1);}
總結
以上是生活随笔為你收集整理的【Android FFMPEG 开发】FFMPEG 初始化 ( 网络初始化 | 打开音视频 | 查找音视频流 )的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Android FFMPEG 开发】C
- 下一篇: 【Android FFMPEG 开发】F