ffmpeg是一個完整的、跨平臺的音訊和視訊錄製、轉換和串流媒體解決方案。
它的官網:https://ffmpeg.org/
這裡有一份中文的檔案:https://ffmpeg.p2hp.com/
在centos上,可以通過yum進行安裝:
yum install epel-release
rpm -Uvh https://download1.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm
yum install ffmpeg ffmpeg-devel
按照上述命令安裝完ffmpeg-devel後,會在 /usr/lib64/ 路徑找到對應的庫
ffmpeg安裝完以後會有三個工具:
ffmpeg還提供一系列的庫,能提供開發者進行編碼開發。
ffmpeg是開源的,原始碼可以直接
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
FFmpeg主要是使用C語言編寫的,由於FFmpeg需要對音訊和視訊進行底層處理,包括解碼、編碼、封裝、解封裝等操作,因此選擇C語言是非常合適的,因為它可以提供對底層作業系統和硬體的直接存取。
FFmpeg的Libavutil庫提供了許多方法和功能,用於在多媒體處理中進行通用的實用工具和基本功能。以下是一些常見的Libavutil庫提供的方法和功能:
av_malloc()
和 av_mallocz()
:動態分配記憶體。av_free()
:釋放先前分配的記憶體。av_memcpy_backptr()
:從後向前拷貝記憶體。av_fast_malloc()
:快速分配記憶體。av_strstart()
和 av_stristart()
:檢查字串的字首。av_stristr()
:在字串中查詢子字串,忽略大小寫。av_get_token()
:從輸入字串中提取標記。av_strcasecmp()
和 av_strncasecmp()
:比較字串,忽略大小寫。av_gettime()
:獲取當前時間戳。av_gettime_relative()
:獲取相對時間戳。av_usleep()
:微秒級延遲。av_clipl_int32()
和 av_clipf()
:對整數和浮點數進行範圍限制。av_log2()
:計算以2為底的對數。av_gcd()
:計算最大公約數。av_rescale_q()
:按比例轉換數值。av_be2ne16()
和 av_be2ne32()
:將大端位元組序轉換為本地位元組序。av_memcpy_backptr()
:從後向前拷貝位元組。avio_*
系列函數:用於讀寫位元組流,如開啟、關閉、讀取和寫入檔案。這只是一小部分Libavutil庫提供的方法和功能列表。Libavutil還提供了許多其他有用的函數,用於處理時間戳、計算時間間隔、處理位元組流、顏色空間轉換等等。
更多方法見:http://ffmpeg.org/doxygen/trunk/group__lavu.html
FFmpeg的libavcodec庫是用於音訊和視訊編解碼的核心庫。它提供了豐富的方法和功能,用於處理不同編解碼器的音視訊資料。以下是一些常見的libavcodec庫提供的方法和功能:
avcodec_find_encoder()
和 avcodec_find_decoder()
:查詢編碼器和解碼器。avcodec_open2()
和 avcodec_close()
:開啟和關閉編碼器和解碼器。avcodec_parameters_to_context()
:將編碼器引數轉換為編碼器上下文。avcodec_parameters_alloc()
和 avcodec_parameters_free()
:分配和釋放編碼器引數物件。avcodec_parameters_copy()
:複製編碼器引數。avcodec_parameters_from_context()
:從編碼器上下文中獲取編碼器引數。avcodec_send_packet()
:傳送封包給編碼器或解碼器。avcodec_receive_frame()
:接收解碼器輸出的幀。avcodec_encode_video2()
和 avcodec_encode_audio2()
:編碼視訊和音訊資料。avcodec_decode_video2()
和 avcodec_decode_audio4()
:解碼視訊和音訊資料。av_frame_alloc()
和 av_frame_free()
:分配和釋放幀物件。av_frame_get_best_effort_timestamp()
:獲取最佳時間戳。av_frame_copy()
和 av_frame_copy_props()
:複製幀資料和屬性。av_codec_get_name()
:獲取編解碼器名稱。av_codec_get_tag2()
:獲取編解碼器的四位元組標籤。av_strerror()
:獲取錯誤訊息字串。avcodec_error_to_string()
:將錯誤程式碼轉換為字串。avcodec_get_name()
:獲取編解碼器的名稱。avcodec_get_type()
:獲取編解碼器的型別。這只是一小部分libavcodec庫提供的方法和功能列表。libavcodec庫還提供了更多用於處理音視訊編解碼的功能,如設定編碼引數、處理編碼器的選項、幀格式轉換等。
更多方法見:http://ffmpeg.org/doxygen/trunk/group__libavc.html
FFmpeg的libavformat庫提供了用於音視訊封裝和解封裝的方法和功能。它支援多種音視訊容器格式,如AVI、MP4、MKV等。以下是一些常見的libavformat庫提供的方法和功能:
avformat_open_input()
和 avformat_close_input()
:開啟和關閉媒體檔案。avformat_find_stream_info()
:獲取媒體檔案的流資訊。avformat_alloc_context()
和 avformat_free_context()
:分配和釋放格式上下文。av_find_best_stream()
:查詢最佳的音視訊流。av_read_frame()
:讀取音視訊幀。av_seek_frame()
:在媒體檔案中進行幀級別的跳轉。av_write_frame()
:寫入音視訊幀。avformat_write_header()
和 avformat_write_trailer()
:寫入封裝格式的頭部和尾部。avio_open()
和 avio_close()
:開啟和關閉封裝格式的IO上下文。avformat_new_stream()
:建立新的音視訊流。av_stream_get_end_pts()
:獲取流的結束時間戳。av_stream_get_r_frame_rate()
:獲取流的影格率。avformat_alloc_output_context2()
:分配輸出格式上下文。avformat_alloc_output_context2()
:獲取輸入格式上下文的引數。av_rescale_q()
:按比例轉換時間戳。av_guess_frame_rate()
:猜測影格率。av_strerror()
:獲取錯誤訊息字串。avformat_version()
:獲取libavformat庫的版本號。av_dump_format()
:輸出媒體檔案的格式資訊。這只是一小部分libavformat庫提供的方法和功能列表。libavformat庫還提供了更多用於音視訊封裝和解封裝的功能,如後設資料操作、時間碼處理、流選擇、封裝格式的選項設定等。
更多方法見:http://ffmpeg.org/doxygen/trunk/group__libavf.html
FFmpeg的libavdevice庫提供了與音視訊裝置互動的方法和功能。它允許您進行音訊和視訊的採集和播放,並提供了與裝置的互動介面。以下是一些常見的libavdevice庫提供的方法和功能:
avdevice_register_all()
:註冊所有可用的裝置。avdevice_list_devices()
:列出可用的音視訊裝置。avdevice_get_input_list()
:獲取輸入裝置列表。avdevice_get_output_list()
:獲取輸出裝置列表。avdevice_open()
和 avdevice_close()
:開啟和關閉裝置。avdevice_capabilities_create()
和 avdevice_capabilities_free()
:建立和釋放裝置引數物件。avdevice_list_input_sources()
和 avdevice_list_output_sinks()
:列出輸入源和輸出介面。avdevice_list_formats()
:列出裝置支援的音視訊格式。avdevice_read_packet()
:從裝置讀取音視訊包。avdevice_write_packet()
:向裝置寫入音視訊包。av_strerror()
:獲取錯誤訊息字串。avdevice_version()
:獲取libavdevice庫的版本號。更多方法見:http://ffmpeg.org/doxygen/trunk/group__lavd.html
FFmpeg的libavfilter庫提供了音視訊濾鏡處理的方法和功能。它允許您對音視訊資料進行各種濾鏡和效果的處理,如裁剪、縮放、旋轉、色彩調整等。以下是一些常見的libavfilter庫提供的方法和功能:
avfilter_register_all()
:註冊所有可用的濾鏡。avfilter_graph_alloc()
和 avfilter_graph_free()
:建立和釋放濾鏡圖。avfilter_graph_parse2()
:解析濾鏡圖的字串描述。avfilter_get_by_name()
:通過名稱獲取濾鏡。avfilter_graph_create_filter()
:建立濾鏡範例。avfilter_init_str()
:初始化濾鏡引數。av_buffersrc_add_frame()
:向輸入緩衝區新增幀資料。av_buffersink_get_frame()
:從輸出緩衝區獲取幀資料。avfilter_inout_alloc()
和 avfilter_inout_free()
:建立和釋放輸入輸出結構。avfilter_graph_config()
:設定濾鏡圖。av_strerror()
:獲取錯誤訊息字串。avfilter_version()
:獲取libavfilter庫的版本號。FFmpeg的libswscale庫提供了影象縮放和顏色空間轉換的方法和功能。它用於對視訊幀進行大小調整、畫素格式轉換和色彩空間轉換等操作。以下是一些常見的libswscale庫提供的方法和功能:
sws_getContext()
和 sws_freeContext()
:建立和釋放影象縮放上下文。sws_scale()
:縮放和轉換影象。sws_setColorspaceDetails()
:設定顏色空間細節。sws_getCachedContext()
和 sws_getContext()
:獲取和設定影象縮放上下文的快取。sws_convertPalette8ToPacked32()
:將8位元調色盤轉換為32位元色彩。sws_setColorspaceDetails()
:設定顏色空間細節。sws_strerror()
:獲取錯誤訊息字串。swscale_version()
:獲取libswscale庫的版本號。FFmpeg的libswresample庫提供了音訊重取樣和格式轉換的方法和功能。它用於對音訊資料進行取樣率、通道佈局和樣本格式的轉換。以下是一些常見的libswresample庫提供的方法和功能:
swr_alloc()
和 swr_free()
:建立和釋放音訊重取樣上下文。swr_init()
:初始化音訊重取樣上下文。swr_convert()
:進行音訊重取樣。swr_config_frame()
:設定輸入/輸出音訊幀的引數。swr_set_compensation()
:設定音訊重取樣補償。swr_alloc_set_opts()
:設定輸入/輸出音訊幀的引數並建立音訊重取樣上下文。swr_convert_frame()
:進行音訊重取樣並輸出音訊幀。swr_get_delay()
:獲取重取樣的延遲。swr_inject_silence()
:注入靜音樣本。swresample_strerror()
:獲取錯誤訊息字串。swresample_version()
:獲取libswresample庫的版本號。我現在有一個mp4檔案,要讀取這個檔案應該怎麼操作呢?
我是按照簽名說的yum的方式安裝ffmpeg-devel,它的
動態庫地址為:/user/lib64/
header標頭檔案地址為:/usr/include/ffmpeg/libavcodec/
在程式中直接參照就行
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
以下是一段讀取網際網路mp4的程式碼。
#include <iostream>
extern "C"
{
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
}
int main() {
std::cout << "start read url mp4" << std::endl;
// 做註冊處理
av_register_all();
avformat_network_init();
AVFormatContext *inputContext = NULL;
// 開啟一個url的資訊
std::string url = "https://demo.com/BigBuckBunny.mp4";
int ret = avformat_open_input(&inputContext, url.c_str(), NULL, NULL);
if ( ret != 0) {
// 開啟檔案失敗,處理錯誤
// 可以通過呼叫 av_strerror() 函數將錯誤碼轉換為可讀的錯誤訊息
char errorStr[AV_ERROR_MAX_STRING_SIZE];
av_strerror(ret, errorStr, sizeof(errorStr));
printf("Failed to open input file: %s\n", errorStr);
return ret;
}
ret = avformat_find_stream_info(inputContext, NULL);
if (ret < 0) {
char errorStr[AV_ERROR_MAX_STRING_SIZE];
av_strerror(ret, errorStr, sizeof(errorStr));
printf("Failed to avformat_find_stream_info file: %s\n", errorStr);
return ret;
}
// 輸出AVFormatContent資訊
av_dump_format(inputContext, -1, url.c_str(), 0);
for (int i = 0; i < inputContext->nb_streams; i++) {
AVStream *stream = inputContext->streams[i];
if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
// 處理音訊流
}
else if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
// 處理視訊流
}
int64_t duration = stream->duration;
std::cout << duration << std::endl;
}
avformat_close_input(&inputContext);
std::cout << "ok" << std::endl;
return 0;
}
輸出:
start read url mp4
Input #-1, mov,mp4,m4a,3gp,3g2,mj2, from 'https://demo.com/BigBuckBunny.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: isomavc1mp42
creation_time : 2010-01-10T08:29:06.000000Z
Duration: 00:09:56.47, start: 0.000000, bitrate: 2119 kb/s
Stream #-1:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 125 kb/s (default)
Metadata:
creation_time : 2010-01-10T08:29:06.000000Z
handler_name : (C) 2007 Google Inc. v08.13.2007.
Stream #-1:1(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 1991 kb/s, 24 fps, 24 tbr, 24k tbn, 48 tbc (default)
Metadata:
creation_time : 2010-01-10T08:29:06.000000Z
handler_name : (C) 2007 Google Inc. v08.13.2007.
26304512
14315000
ok
這裡的關鍵的函數呼叫邏輯如下:
AVInputFormat
:指向輸入格式的指標,包含解封裝函數等資訊。AVStream
:指向音視訊流的陣列,每個流都有對應的索引。nb_streams
:音視訊流的數量。duration
:音視訊檔的總時長。bit_rate
:音視訊檔的位元率。metadata
:後設資料,包含了檔案的附加資訊,如標題、作者、描述等。實時瞭解作者更多技術文章,技術心得,請關注微信公眾號「軒脈刃的刀光劍影」
本文基於署名-非商業性使用 3.0許可協定釋出,歡迎轉載,演繹,但是必須保留本文的署名葉劍峰(包含連結http://www.cnblogs.com/yjf512/),且不得用於商業目的。如您有任何疑問或者授權方面的協商,請與我聯絡。