最簡單的基于 FFmpeg 的音頻解碼器

最簡單的基于 FFmpeg 的音頻解碼器

  • 最簡單的基于 FFmpeg 的音頻解碼器
    • 正文
    • 參考
    • 工程文件下載

參考雷霄驊博士的文章,鏈接:最簡單的基于FFMPEG+SDL的音頻播放器:拆分-解碼器和播放器

最簡單的基于 FFmpeg 的音頻解碼器

正文

FFmpeg 音頻解碼器實現了音頻數據到 PCM 采樣數據的解碼。

如果你不會 Vusual Studio 下 FFmpeg 的項目配置,可以看我寫的教程:Visual Studio 2015 中 FFmpeg 開發環境的搭建。

源代碼:

// Simplest FFmpeg Audio Decoder.cpp : 定義控制臺應用程序的入口點。/**
* 最簡單的基于 FFmpeg 的音頻解碼器
* Simplest FFmpeg Audio Decoder
*
* 劉文晨 Liu Wenchen
* 812288728@qq.com
* 電子科技大學/電子信息
* University of Electronic Science and Technology of China / Electronic and Information Science
* https://blog.csdn.net/ProgramNovice
*
* 本程序可以將音頻碼流(MP3,AAC等)解碼為 PCM 采樣數據。
*
* This software decode audio streams (MP3, ACC...) to PCM data.
*
*/#include "stdafx.h"#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define __STDC_CONSTANT_MACROS
#ifdef _WIN32
// Windows
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswresample/swresample.h"
};
#else
// Linux
#endif// 1 second of 48kHz 32bit audio,單位是字節
#define MAX_AUDIO_FRAME_SIZE 192000 int main(int argc, char* argv[])
{// 結構體及變量定義AVFormatContext* pFormatCtx;int i, audioStream;AVCodecContext* pCodecCtx;AVCodec* pCodec;AVPacket* packet;uint8_t* out_buffer;AVFrame* pFrame;int ret;uint32_t len = 0;int got_picture;int index = 0;int64_t in_channel_layout;struct SwrContext *au_convert_ctx;// 輸出文件路徑FILE *pFile = fopen("output.pcm", "wb");// 輸入文件路徑char url[] = "skycity.mp3";// 注冊支持的所有的文件格式(容器)及其對應的 CODEC,只需要調用一次av_register_all();// 對網絡庫進行全局初始化(加載 socket 庫以及網絡加密協議相關的庫,為后續使用網絡相關提供支持)// 注意:此函數僅用于解決舊 GnuTLS 或 OpenSSL 庫的線程安全問題。// 如果 libavformat 鏈接到這些庫的較新版本,或者不使用它們,則無需調用此函數。// 否則,需要在使用它們的任何其他線程啟動之前調用此函數。avformat_network_init();// 使用默認參數分配并初始化一個 AVFormatContext 對象pFormatCtx = avformat_alloc_context();// 打開輸入媒體流,分配編解碼器上下文、解復用上下文、I/O 上下文if (avformat_open_input(&pFormatCtx, url, NULL, NULL) != 0){printf("Can't open input stream.\n");return -1;}// 讀取媒體文件的數據包以獲取媒體流信息if (avformat_find_stream_info(pFormatCtx, NULL) < 0){printf("Can't find stream information.\n");return -1;}printf("---------------- File Information ---------------\n");// 將 AVFormatContext 結構體中媒體文件的信息進行格式化輸出av_dump_format(pFormatCtx, 0, url, false);printf("-------------------------------------------------\n");audioStream = -1;for (i = 0; i < pFormatCtx->nb_streams; i++){if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO){audioStream = i;break;}}if (audioStream == -1){printf("Can't find a audio stream.\n");return -1;}// pCodecCtx 是指向音頻流的編解碼器上下文的指針pCodecCtx = pFormatCtx->streams[audioStream]->codec;// 查找 ID 為 pCodecCtx->codec_id 的已注冊的音頻流解碼器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("Can't open codec.\n");return -1;}// 為 packet 分配空間packet = (AVPacket *)av_malloc(sizeof(AVPacket));// 將 packet 中的可選字段初始化為默認值av_init_packet(packet);// 輸出音頻參數// 通道類型:雙聲道uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO;int out_nb_samples = pCodecCtx->frame_size;// 采樣格式:pcm_s16le(整型 16bit)AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_S16;// 采樣率:44100int out_sample_rate = 44100;int out_channels = av_get_channel_layout_nb_channels(out_channel_layout);int out_buffer_size = av_samples_get_buffer_size(NULL, out_channels, out_nb_samples, out_sample_fmt, 1);out_buffer = (uint8_t *)av_malloc(MAX_AUDIO_FRAME_SIZE * 2);pFrame = av_frame_alloc();// 根據聲道數目獲取聲道布局in_channel_layout = av_get_default_channel_layout(pCodecCtx->channels);// 創建重采樣結構體 SwrContext 對象au_convert_ctx = swr_alloc();// 設置重采樣的轉換參數au_convert_ctx = swr_alloc_set_opts(au_convert_ctx, out_channel_layout, out_sample_fmt, out_sample_rate,in_channel_layout, pCodecCtx->sample_fmt, pCodecCtx->sample_rate, 0, NULL);// 初始化 SwrContext 對象swr_init(au_convert_ctx);// 讀取碼流中的音頻若干幀或者視頻一幀while (av_read_frame(pFormatCtx, packet) >= 0){if (packet->stream_index == audioStream){// 解碼 packet 中的音頻數據,pFrame 存儲解碼數據ret = avcodec_decode_audio4(pCodecCtx, pFrame, &got_picture, packet);if (ret < 0){printf("Error in decoding audio frame.\n");return -1;}if (got_picture > 0){// 進行格式轉換,返回值為實際轉換的采樣數swr_convert(au_convert_ctx, &out_buffer, MAX_AUDIO_FRAME_SIZE, (const uint8_t **)pFrame->data, pFrame->nb_samples);// 打印每一幀的信息printf("index: %5d\t pts: %lld\t packet size: %d\n", index, packet->pts, packet->size);// 向輸出文件中寫入 PCM 數據fwrite(out_buffer, 1, out_buffer_size, pFile);index++;}}// 清空 packet 里面的數據av_free_packet(packet);}// 釋放 SwrContext 對象swr_free(&au_convert_ctx);// 關閉文件指針fclose(pFile);// 釋放內存av_free(out_buffer);// 關閉解碼器avcodec_close(pCodecCtx);// 關閉輸入音頻文件avformat_close_input(&pFormatCtx);return 0;
}

本程序可以直接在 Visual Studio 2015 上運行。

程序運行后,會解碼下面的音頻文件。

在這里插入圖片描述

解碼后的 PCM 采樣數據被保存成了一個文件,名叫 output.pcm。使用 Adobe Audition 設置采樣率等信息后可以查看 PCM 的內容。

在這里插入圖片描述

在這里插入圖片描述

參考

05 FFmpeg4.4源碼分析–解碼

error C4996: ‘fopen’: This function or variable may be unsafe 的解決方法

工程文件下載

GitHub:UestcXiye / Simplest-FFmpeg-Audio-Decoder

CSDN:Simplest FFmpeg Audio Decoder.zip

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/210991.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/210991.shtml
英文地址,請注明出處:http://en.pswp.cn/news/210991.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【ArcGIS微課1000例】0080:ArcGIS將shp轉json(geojson)案例教程

本文以案例的形式,講述在ArcGIS軟件中,將矢量數據轉為GeoJSON的方法。 擴展閱讀:【GIS風暴】GeoJSON數據格式案例全解 文章目錄 一、GeoJson簡介二、ArcGIS將矢量數據轉為GeoJSON一、GeoJson簡介 GeoJSON是一種基于JSON的地理空間數據交換格式,它定義了幾種類型JSON對象以…

Spring Cloud Gateway 網關的基礎使用

1. 什么是網關&#xff1f;網關有什么用&#xff1f; 在微服務架構中&#xff0c;網關就是一個提供統一訪問地址的組件&#xff0c;它解決了內部微服務與外部的交互問題。網關主要負責流量的路由和轉發&#xff0c;將外部請求引到對應的微服務實例上。同時提供身份認證、授權、…

Spring-Boot---配置文件

文章目錄 配置文件的作用配置文件的格式PropertiesProperties基本語法讀取Properties配置文件 ymlyml基本語法讀取yml配置文件 Properties VS Yml 配置文件的作用 整個項目中所有重要的數據都是在配置文件中配置的&#xff0c;具有非常重要的作用。比如&#xff1a; 數據庫的…

230. 二叉搜索樹中第K小的元素 --力扣 --JAVA

題目 給定一個二叉搜索樹的根節點 root &#xff0c;和一個整數 k &#xff0c;請你設計一個算法查找其中第 k 個最小元素&#xff08;從 1 開始計數&#xff09;。 解題思路 利用List存儲數據&#xff1b;遍歷整個樹&#xff0c;讀取數各個節點的value&#xff1b;對value進行…

Python繪制多分類ROC曲線

目錄 1 數據集介紹 1.1 數據集簡介 1.2 數據預處理 2隨機森林分類 2.1 數據加載 2.2 參數尋優 2.3 模型訓練與評估 3 繪制十分類ROC曲線 第一步&#xff0c;計算每個分類的預測結果概率 第二步&#xff0c;畫圖數據準備 第三步&#xff0c;繪制十分類ROC曲線 1 數據集…

【數據結構】——排序篇(上)

前言&#xff1a;前面我們已經學過了許許多多的排序方法&#xff0c;如冒泡排序&#xff0c;選擇排序&#xff0c;堆排序等等&#xff0c;那么我們就來將排序的方法總結一下。 我們的排序方法包括以下幾種&#xff0c;而快速排序和歸并排序我們后面進行詳細的講解。 直接插入…

Qt實現二維碼生成和識別

一、簡介 QZxing開源庫: 生成和識別條碼和二維碼 下載地址&#xff1a;https://gitcode.com/mirrors/ftylitak/qzxing/tree/master 二、編譯與使用 1.下載并解壓&#xff0c;解壓之后如圖所示 2.編譯 打開src目錄下的QZXing.pro&#xff0c;選擇合適的編譯器進行編譯 最后生…

util.js

一、util.js是什么&#xff1f; 1、util.js是Node.js提供的一個工具庫&#xff0c;主要用于輔助實現JavaScript代碼的通用功能。 2、除了Node.js中內置的模塊外&#xff0c;util.js是Node.js中最核心的模塊之一。 3、通過util.js&#xff0c;開發者可以輕松實現JavaScript常…

Unity 資源管理之StreamingAssets

StreamingAssets也是Unity中特殊的文件夾&#xff0c;用于存放運行時可以直接訪問的資源。StreamingAssets一般存放數據或配置文件、圖片、視頻資源等。 StreamingAssets的文件路徑可以通過Application.streamingAssetsPath來獲取。 加載或訪問使用WWW類或UnityWebRequest類。…

MIT6S081-Lab2總結

大家好&#xff0c;我叫徐錦桐&#xff0c;個人博客地址為www.xujintong.com&#xff0c;github地址為https://github.com/xjintong。平時記錄一下學習計算機過程中獲取的知識&#xff0c;還有日常折騰的經驗&#xff0c;歡迎大家訪問。 Lab2就是了解一下xv6的系統調用流程&…

Java - Synchronized的鎖升級之路

Synchronized鎖 Synchronized在Java JVM里的實現是基于進入和退出Monitor對象來實現方法同步和代碼塊同步的 monitor enter指令是在編譯后插入到同步代碼塊的開始位置 而monitor exit是插入到方法結束處和異常處 JVM要保證每個monitor enter必須有對應的monitor exit與之配對。…

解決服務端渲染程序SSR運行時報錯: ReferenceError: document is not defined

現象&#xff1a; 原因&#xff1a; 該錯誤表明在服務端渲染 (SSR) 過程中&#xff0c;有一些代碼嘗試在沒有瀏覽器環境的情況下執行與瀏覽器相關的操作。這在服務端渲染期間是一個常見的問題&#xff0c;因為在服務端渲染期間是沒有瀏覽器 API。 解決辦法&#xff1a; 1. 修…

bat腳本之while

在批處理&#xff08;BAT&#xff09;腳本中&#xff0c;while循環是一種常用的控制流結構&#xff0c;用于在滿足特定條件的情況下重復執行一段代碼。 while循環的基本語法如下&#xff1a; while [ condition ] do command1 command2 ... commandN done這里的 cond…

【2023傳智杯-新增場次】第六屆傳智杯程序設計挑戰賽AB組-DEF題復盤解題分析詳解【JavaPythonC++解題筆記】

本文僅為【2023傳智杯-第二場】第六屆傳智杯程序設計挑戰賽-題目解題分析詳解的解題個人筆記,個人解題分析記錄。 本文包含:第六屆傳智杯程序設計挑戰賽題目、解題思路分析、解題代碼、解題代碼詳解 文章目錄 一.前言二.賽題題目D題題目-E題題目-F題題目-二.賽題題解D題題解-…

深入理解Sentinel系列-1.初識Sentinel

&#x1f44f;作者簡介&#xff1a;大家好&#xff0c;我是愛吃芝士的土豆倪&#xff0c;24屆校招生Java選手&#xff0c;很高興認識大家&#x1f4d5;系列專欄&#xff1a;Spring源碼、JUC源碼、Kafka原理、分布式技術原理&#x1f525;如果感覺博主的文章還不錯的話&#xff…

待做-待補充-每個節點做事,時間,以及與角度的關系

文章目錄 待定內容紅黑樹應用場景限制什么是二叉樹遍歷遞歸遍歷1.前序遍歷 進入節點時2.中序遍歷 遍歷完左子樹回到節點。此操作需要等到所有左樹節點做完后才會做3.后序遍歷 遍歷完左右子樹回到節點。左右子樹的所有節點都做完操作后&#xff0c;回到當前節點才會做此操作 …

如何搭建自己的直播電商系統?

當下&#xff0c;傳統的圖文電商模式已經走向沒落&#xff0c;視頻電商備受追捧。抖音、快手、小紅書、京東、淘寶、拼多多都在發力直播電商業務&#xff0c;尤其是以抖音為首的直播電商備受用戶歡迎&#xff0c;它具有實時直播和強互動的特點&#xff0c;是傳統電商所不具備的…

<HarmonyOS第一課>保存應用數據【課后考核】

【習題】保存應用數據 判斷題 首選項是關系型數據庫。 錯誤(False) 應用中涉及到Student信息&#xff0c;如包含姓名&#xff0c;性別&#xff0c;年齡&#xff0c;身高等信息可以用首選項來存儲。 錯誤(False) 同一應用或進程中每個文件僅存在一個Preferences實例。 正確(T…

最長子串問題(LCS)--動態規劃解法

題目描述&#xff1a; 如果Z既是X的子串&#xff0c;又是Y的子串&#xff0c;則稱Z為X和Y的公共子串。 如果給定X、Y&#xff0c;求出最長Z及其長度。 注意&#xff1a;這里求的不是子序列&#xff0c;兩者的意思并不相同。子串要求連續&#xff0c;子序列并不需要。 如果想…

simulinkveristandlabview聯合仿真環境搭建

目錄 開篇廢話 軟件版本 明確需求 軟件安裝 matlab2020a veristand2020 R4 VS2017 VS2010 軟件安裝驗證 軟件資源分享 開篇廢話 推免之后接到的第一個讓人難繃的活&#xff0c;網上開源的軟件資料和成功的案例很少&#xff0c;查來查去就那么幾篇&#xff0c;而且版本…