国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

FFmpeg代碼實(shí)現(xiàn)抽取音頻、視頻數(shù)據(jù)

這篇具有很好參考價(jià)值的文章主要介紹了FFmpeg代碼實(shí)現(xiàn)抽取音頻、視頻數(shù)據(jù)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

今天開始擼代碼,首先使用FFmpeg的API抽取一個(gè)MP4文件的音頻數(shù)據(jù)。

IDE

應(yīng)該是第一次在Mac上做C/C++開發(fā),糾結(jié)過后選擇使用CLion 開發(fā)。CLion是 JetBrains下專門用來開發(fā)C/C++的IDE,已經(jīng)用習(xí)慣了Android studio和IntelliJ IDEA ,所以CLion用起來還是很順手的。

在新建一個(gè)C項(xiàng)目后,需要把FFmpeg的庫導(dǎo)入才能正常運(yùn)行。我們修改項(xiàng)目的CMakeLists.txt文件。

ffmpeg讀取mp4文件,ffmpeg

抽取音頻AAC數(shù)據(jù)

其實(shí)我們要做的主要就是一個(gè)文件的操作,把一個(gè)文件打開,從里面拿出它的一部分?jǐn)?shù)據(jù),再把這部分?jǐn)?shù)據(jù)放到另一個(gè)文件中保存。

定義參數(shù)

#include <stdio.h>
#include <libavutil/log.h>
#include <libavformat/avformat.h>

//上下文
AVFormatContext *fmt_ctx = NULL;
AVFormatContext *ofmt_ctx = NULL;

//支持各種各樣的輸出文件格式,MP4,F(xiàn)LV,3GP等等
AVOutputFormat *output_fmt = NULL;

//輸入流
AVStream *in_stream = NULL;

//輸出流
AVStream *out_stream = NULL;

//存儲(chǔ)壓縮數(shù)據(jù)
AVPacket packet;

//要拷貝的流
int audio_stream_index = -1;

1.打開輸入文件,提取參數(shù)

//打開輸入文件,關(guān)于輸入文件的所有就保存到fmt_ctx中了
err_code = avformat_open_input(&fmt_ctx, src_fileName, NULL, NULL);

if (err_code < 0) {
    av_log(NULL, AV_LOG_ERROR, "cant open file:%s\n", av_err2str(err_code));
    return -1;
}

if(fmt_ctx->nb_streams<2){
      //流數(shù)小于2,說明這個(gè)文件音頻、視頻流這兩條都不能保證,輸入文件有錯(cuò)誤 
      av_log(NULL, AV_LOG_ERROR, "輸入文件錯(cuò)誤,流不足2條\n");
      exit(1);
 }

 //拿到文件中音頻流
 in_stream = fmt_ctx->streams[1];
 //參數(shù)信息
 AVCodecParameters *in_codecpar = in_stream->codecpar;

//找到最好的音頻流
audio_stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
    if(audio_stream_index < 0){
        av_log(NULL, AV_LOG_DEBUG, "尋找最好音頻流失敗,請(qǐng)檢查輸入文件!\n");
        return AVERROR(EINVAL);
}

2.準(zhǔn)備輸出文件,輸出流

// 輸出上下文
ofmt_ctx = avformat_alloc_context();

//根據(jù)目標(biāo)文件名生成最適合的輸出容器
output_fmt = av_guess_format(NULL,dst_fileName,NULL);
if(!output_fmt){
    av_log(NULL, AV_LOG_DEBUG, "根據(jù)目標(biāo)生成輸出容器失?。n");
    exit(1);
}

ofmt_ctx->oformat = output_fmt;

//新建輸出流
 out_stream = avformat_new_stream(ofmt_ctx, NULL);
 if(!out_stream){
      av_log(NULL, AV_LOG_DEBUG, "創(chuàng)建輸出流失??!\n");
      exit(1);
 }

3. 數(shù)據(jù)拷貝

3.1 參數(shù)信息

// 將參數(shù)信息拷貝到輸出流中,我們只是抽取音頻流,并不做音頻處理,所以這里只是Copy
if((err_code = avcodec_parameters_copy(out_stream->codecpar, in_codecpar)) < 0 ){
    av_strerror(err_code, errors, ERROR_STR_SIZE);
    av_log(NULL, AV_LOG_ERROR,"拷貝編碼參數(shù)失?。? %d(%s)\n",
           err_code, errors);
}

3.2 初始化AVIOContext

//初始化AVIOContext,文件操作由它完成
if((err_code = avio_open(&ofmt_ctx->pb, dst_fileName, AVIO_FLAG_WRITE)) < 0) {
    av_strerror(err_code, errors, 1024);
    av_log(NULL, AV_LOG_DEBUG, "Could not open file %s, %d(%s)\n",
           dst_fileName,
           err_code,
           errors);
    exit(1);
}

3.3 開始拷貝

//初始化 AVPacket, 我們從文件中讀出的數(shù)據(jù)會(huì)暫存在其中
av_init_packet(&packet);
packet.data = NULL;
packet.size = 0;

// 寫頭部信息
if (avformat_write_header(ofmt_ctx, NULL) < 0) {
    av_log(NULL, AV_LOG_DEBUG, "Error occurred when opening output file");
    exit(1);
}


//每讀出一幀數(shù)據(jù)
while(av_read_frame(fmt_ctx, &packet) >=0 ){
    if(packet.stream_index == audio_stream_index){
        //時(shí)間基計(jì)算,音頻pts和dts一致
        packet.pts = av_rescale_q_rnd(packet.pts, in_stream->time_base, out_stream->time_base, (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));
        packet.dts = packet.pts;
        packet.duration = av_rescale_q(packet.duration, in_stream->time_base, out_stream->time_base);
        packet.pos = -1;
        packet.stream_index = 0;
        //將包寫到輸出媒體文件
        av_interleaved_write_frame(ofmt_ctx, &packet);
        //減少引用計(jì)數(shù),避免內(nèi)存泄漏
        av_packet_unref(&packet);
    }
}

//寫尾部信息
av_write_trailer(ofmt_ctx);

//最后別忘了釋放內(nèi)存
avformat_close_input(&fmt_ctx);
avio_close(ofmt_ctx->pb);

執(zhí)行

./MyC /Users/david/Desktop/1080p.mov /Users/david/Desktop/test.aac

抽取視頻數(shù)據(jù)

抽取視頻信息并保存在文件中的流程甚至代碼和上面抽取音頻基本一致。

//拿到文件中音頻流 或者 視頻流,所有流都在streams數(shù)組中
 in_stream = fmt_ctx->streams[1];

//找到最好的視頻流
video_stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);

packet.dts = av_rescale_q_rnd(packet.dts, in_stream->time_base, out_stream->time_base, (AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX));

基本上就是一些參數(shù)的改變,所有流程和代碼保持不變,就可以把一個(gè)音視頻文件中的視頻數(shù)據(jù)抽取出來了,mp4、mov等格式隨便,就是這么簡(jiǎn)單。。。

更新

====== 貼出完整代碼,并對(duì)代碼中的一些細(xì)節(jié)做出優(yōu)化========

#include <stdio.h>
#include <libavutil/log.h>
#include <libavformat/avio.h>
#include <libavformat/avformat.h>

#define ERROR_STR_SIZE 1024

int main(int argc, char *argv[]) {
    int err_code;
    char errors[1024];

    char *src_filename = NULL;
    char *dst_filename = NULL;

    int audio_stream_index;

    //上下文
    AVFormatContext *fmt_ctx = NULL;
    AVFormatContext *ofmt_ctx = NULL;

    //支持各種各樣的輸出文件格式,MP4,F(xiàn)LV,3GP等等
    AVOutputFormat *output_fmt = NULL;

    AVStream *in_stream = NULL;
    AVStream *out_stream = NULL;

    AVPacket pkt;

    av_log_set_level(AV_LOG_DEBUG);

    if (argc < 3) {
        av_log(NULL, AV_LOG_DEBUG, "argc < 3!\n");
        return -1;
    }

    src_filename = argv[1];
    dst_filename = argv[2];

    if (src_filename == NULL || dst_filename == NULL) {
        av_log(NULL, AV_LOG_DEBUG, "src or dts file is null!\n");
        return -1;
    }


    if ((err_code = avformat_open_input(&fmt_ctx, src_filename, NULL, NULL)) < 0) {
        av_strerror(err_code, errors, 1024);
        av_log(NULL, AV_LOG_DEBUG, "打開輸入文件失敗: %s, %d(%s)\n",
               src_filename,
               err_code,
               errors);
        return -1;
    }

    if ((err_code = avformat_find_stream_info(fmt_ctx, NULL)) < 0) {
        av_strerror(err_code, errors, 1024);
        av_log(NULL, AV_LOG_DEBUG, "failed to find stream info: %s, %d(%s)\n",
               src_filename,
               err_code,
               errors);
        return -1;
    }

    av_dump_format(fmt_ctx, 0, src_filename, 0);

    if (fmt_ctx->nb_streams < 2) {
        //流數(shù)小于2,說明這個(gè)文件音頻、視頻流這兩條都不能保證,輸入文件有錯(cuò)誤
        av_log(NULL, AV_LOG_ERROR, "輸入文件錯(cuò)誤,流不足2條\n");
        exit(1);
    }

    //拿到文件中音頻流
    /**只需要修改這里AVMEDIA_TYPE_VIDEO參數(shù)**/
    audio_stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO /*AVMEDIA_TYPE_VIDEO*/, -1, -1, NULL, 0);
    if (audio_stream_index < 0) {
        av_log(NULL, AV_LOG_DEBUG, " 獲取音頻流失敗%s,%s\n",
               av_get_media_type_string(AVMEDIA_TYPE_AUDIO),
               src_filename);
        return AVERROR(EINVAL);
    }

    in_stream = fmt_ctx->streams[audio_stream_index];
    //參數(shù)信息
    AVCodecParameters *in_codecpar = in_stream->codecpar;


    // 輸出上下文
    ofmt_ctx = avformat_alloc_context();

    //根據(jù)目標(biāo)文件名生成最適合的輸出容器
    output_fmt = av_guess_format(NULL, dst_filename, NULL);
    if (!output_fmt) {
        av_log(NULL, AV_LOG_DEBUG, "根據(jù)目標(biāo)生成輸出容器失??!\n");
        exit(1);
    }

    ofmt_ctx->oformat = output_fmt;

    //新建輸出流
    out_stream = avformat_new_stream(ofmt_ctx, NULL);
    if (!out_stream) {
        av_log(NULL, AV_LOG_DEBUG, "創(chuàng)建輸出流失??!\n");
        exit(1);
    }

    // 將參數(shù)信息拷貝到輸出流中,我們只是抽取音頻流,并不做音頻處理,所以這里只是Copy
    if ((err_code = avcodec_parameters_copy(out_stream->codecpar, in_codecpar)) < 0) {
        av_strerror(err_code, errors, ERROR_STR_SIZE);
        av_log(NULL, AV_LOG_ERROR,
               "拷貝編碼參數(shù)失?。? %d(%s)\n",
               err_code, errors);
    }

    out_stream->codecpar->codec_tag = 0;

    //初始化AVIOContext,文件操作由它完成
    if ((err_code = avio_open(&ofmt_ctx->pb, dst_filename, AVIO_FLAG_WRITE)) < 0) {
        av_strerror(err_code, errors, 1024);
        av_log(NULL, AV_LOG_DEBUG, "文件打開失敗 %s, %d(%s)\n",
               dst_filename,
               err_code,
               errors);
        exit(1);
    }



    av_dump_format(ofmt_ctx, 0, dst_filename, 1);


    //初始化 AVPacket, 我們從文件中讀出的數(shù)據(jù)會(huì)暫存在其中
    av_init_packet(&pkt);
    pkt.data = NULL;
    pkt.size = 0;


    // 寫頭部信息
    if (avformat_write_header(ofmt_ctx, NULL) < 0) {
        av_log(NULL, AV_LOG_DEBUG, "寫入頭部信息失敗!");
        exit(1);
    }

    //每讀出一幀數(shù)據(jù)
    while (av_read_frame(fmt_ctx, &pkt) >= 0) {
        if (pkt.stream_index == audio_stream_index) {
            pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base,
                                       (AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
            pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base,
                                       (AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));

            pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
            pkt.pos = -1;
            pkt.stream_index = 0;
            //將包寫到輸出媒體文件
            av_interleaved_write_frame(ofmt_ctx, &pkt);
            //減少引用計(jì)數(shù),避免內(nèi)存泄漏
            av_packet_unref(&pkt);
        }
    }

    //寫尾部信息
    av_write_trailer(ofmt_ctx);

    //最后別忘了釋放內(nèi)存
    avformat_close_input(&fmt_ctx);
    avio_close(ofmt_ctx->pb);

    return 0;
}

./MyC /Users/david/Desktop/1080p.mov /Users/david/Desktop/test.aac

只需要修改av_find_best_stream中的參數(shù),執(zhí)行以下命令就可以將視頻流提取,成為單獨(dú)的視頻文件

./MyC /Users/david/Desktop/1080p.mov /Users/david/Desktop/test1.mp4

./MyC /Users/david/Desktop/1080p.mov /Users/david/Desktop/test2.mov

原文 FFmpeg代碼實(shí)現(xiàn)抽取音頻、視頻數(shù)據(jù) - 掘金?文章來源地址http://www.zghlxwxcb.cn/news/detail-721824.html

到了這里,關(guān)于FFmpeg代碼實(shí)現(xiàn)抽取音頻、視頻數(shù)據(jù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • qt+ffmpeg 實(shí)現(xiàn)音視頻播放(二)之音頻播放

    qt+ffmpeg 實(shí)現(xiàn)音視頻播放(二)之音頻播放

    通過? avformat_open_input ()?打開媒體文件并分配和初始化? AVFormatContext?? 結(jié)構(gòu)體。 函數(shù)原型如下: int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options); 參數(shù)說明: - `ps`:指向 `AVFormatContext` 結(jié)構(gòu)體指針的指針,用于存儲(chǔ)打開的媒體文件的信息。

    2024年04月22日
    瀏覽(37)
  • OpenAI Whisper + FFmpeg + TTS:動(dòng)態(tài)實(shí)現(xiàn)跨語言視頻音頻翻譯

    本文作者系360奇舞團(tuán)前端開發(fā)工程師 本文介紹了如何結(jié)合 OpenAI Whisper、FFmpeg 和 TTS(Text-to-Speech)技術(shù),以實(shí)現(xiàn)將視頻翻譯為其他語言并更換聲音的過程。我們將探討如何使用 OpenAI Whisper 進(jìn)行語音識(shí)別和翻譯,然后使用 FFmpeg 提取視頻音軌和處理視頻,最后使用 TTS 技術(shù)生成新

    2024年02月09日
    瀏覽(16)
  • 利用FFmpeg實(shí)現(xiàn)錄屏、直播推流、音頻視頻格式轉(zhuǎn)換、剪裁等功能

    一、FFmpeg簡(jiǎn)介。 二、FFmpeg常用參數(shù)及命令。 三、FFmpeg在Unity 3D中的使用。 1、FFmpeg 錄屏。 2、FFmpeg 推流。 3、FFmpeg 其他功能簡(jiǎn)述。 對(duì)于FFmpeg,其官網(wǎng)上是這樣介紹的: FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything th

    2024年02月09日
    瀏覽(28)
  • 使用FFMPEG庫封裝264視頻和acc音頻數(shù)據(jù)到MP4文件中

    使用FFMPEG庫封裝264視頻和acc音頻數(shù)據(jù)到MP4文件中

    ffmepeg 4.4 一段H264的視頻文件 一段acc格式的音頻文件 1.使用avformat_open_input分別打開視頻和音頻文件,初始化其AVFormatContext,使用avformat_find_stream_info獲取編碼器基本信息 2.使用avformat_alloc_output_context2初始化輸出的AVFormatContext結(jié)構(gòu) 3.使用函數(shù)avformat_new_stream給輸出的AVFormatContext結(jié)

    2024年02月11日
    瀏覽(20)
  • ffmpeg視頻音頻命令

    視頻音頻合并,以視頻時(shí)間為主,音頻短了循環(huán) 方法1:混音,視頻權(quán)重0,volume調(diào)節(jié)音量,aloop無限循環(huán),duration:first為第一個(gè)素材的長(zhǎng)度 ffmpeg -i video.mp4 -i audio.mp3 -filter_complex \\\"[1:a]volume=0.5[a1];[a1]aloop=loop=-1:size=2e+09[a2];[0:a][a2]amix=inputs=2:duration=first:weights=\\\'0 1\\\'[a]\\\" -map 0:v -map \\\"[a]\\\"

    2024年02月13日
    瀏覽(23)
  • 利用FFmpeg合并音頻和視頻

    一、FFmpeg 多個(gè)音頻合并的2種方法 多個(gè)mp3文件合并成一個(gè)mp3文件 一種方法是連接到一起 ffmpeg64.exe -i \\\"concat:123.mp3|124.mp3\\\" -acodec copy output.mp3 解釋:-i代表輸入?yún)?shù) ? ? contact:123.mp3|124.mp3代表著需要連接到一起的音頻文件 ? ? ? ? ? ? ? ? ?-acodec copy ?output.mp3 重新編碼并復(fù)制到

    2024年04月10日
    瀏覽(23)
  • FFmpeg從視頻中提取音頻

    FFmpeg從視頻中提取音頻

    參考博客 ffmpeg Documentation FFmpeg最全教程 FFmpeg 提取視頻的音頻 FFMPEG 提取音頻 ffmpeg 給音頻添加封面,ffmpeg對(duì)音視頻metadata相關(guān)操作 查看 使用 FFprobe ffprobe 是一個(gè)多媒體流分析工具。它從多媒體流中收集信息,并且以人類和機(jī)器可讀的形式打印出來。它可以用來檢測(cè)多媒體流的

    2023年04月08日
    瀏覽(31)
  • Vue 3 + ffmpeg + wasm 實(shí)現(xiàn)前端視頻剪輯、音頻剪輯、音波展示、視頻抽幀、gif抽幀、幀播放器、字幕、貼圖、時(shí)間軸、素材軌道

    預(yù)覽 www.bilibili.com/video/BV1YT411Y7YJ 技術(shù)棧: ?? Vue 3、Vue-Router 4、Vite、pnpm、esbuild、TypeScript ?? Pinia 狀態(tài)管理 ?? Tailwind 原子css集成 ?? ffmpeg、wasm 底層音視頻處理集成 功能 多軌道時(shí)間軸,支持幀縮放,時(shí)間縮放 支持多種類型軌道的添加刪除 多功能軌道調(diào)節(jié),支持音視頻軌

    2024年02月11日
    瀏覽(31)
  • 【FFmpeg】ffmpeg 命令行參數(shù) ⑧ ( 使用 ffmpeg 轉(zhuǎn)換封裝格式 | 音視頻編解碼器參數(shù)設(shè)置 | 視頻 幀率 / 碼率 / 分辨率 設(shè)置 | 音頻 碼率 / 采樣率 設(shè)置 )

    【FFmpeg】ffmpeg 命令行參數(shù) ⑧ ( 使用 ffmpeg 轉(zhuǎn)換封裝格式 | 音視頻編解碼器參數(shù)設(shè)置 | 視頻 幀率 / 碼率 / 分辨率 設(shè)置 | 音頻 碼率 / 采樣率 設(shè)置 )

    音視頻 文件 從 采樣 - 處理 - 得到原始數(shù)據(jù)幀隊(duì)列 - 音視頻編碼 - 音視頻包隊(duì)列 - 格式封裝 的過程如下 : 封裝格式 參考 【音視頻原理】音視頻 “ 采樣 - 編碼 - 封裝 過程 “ 和 “ 解封裝 - 解碼 - 播放 過程 “ 分析 ( 視頻采集處理流程 | 音頻采集處理流程 | 音視頻文件解封裝

    2024年04月17日
    瀏覽(101)
  • 音視頻八股文(11)-- ffmpeg 音頻重采樣

    音視頻八股文(11)-- ffmpeg 音頻重采樣

    所謂的重采樣,就是改變?頻的采樣率、sample format、聲道數(shù)等參數(shù),使之按照我們期望的參數(shù)輸出。 為什么要重采樣?當(dāng)然是原有的?頻參數(shù)不滿?我們的需求,?如在FFmpeg解碼?頻的時(shí)候,不同的?源有不同的格式,采樣率等,在解碼后的數(shù)據(jù)中的這些參數(shù)也會(huì)不?致(最

    2024年02月04日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包