通过 libvlc 将音频转换为解压缩 wav

Convert an audio to uncompress wav by libvlc

源代码

#include <vlc/vlc.h>

#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include <vector>

void libvlc_callback(libvlc_event_t const *event, void*)
{
    switch (event->type) {
    case libvlc_MediaMetaChanged:
        std::cout<<__func__<<": libvlc_MediaMetaChanged = "<<event->u.media_meta_changed.meta_type<<std::endl;
        break;
    case libvlc_MediaSubItemAdded:
        std::cout<<__func__<<": libvlc_MediaSubItemAdded = "<<event->u.media_subitem_added.new_child<<std::endl;
        break;
    case libvlc_MediaDurationChanged:
        std::cout<<__func__<<": libvlc_MediaDurationChanged = "
                <<event->u.media_duration_changed.new_duration<<std::endl;
        break;
    case libvlc_MediaParsedChanged:
        std::cout<<__func__<<": libvlc_MediaParsedChanged = "<<event->u.media_parsed_changed.new_status<<std::endl;
        break;
    case libvlc_MediaFreed:
        std::cout<<__func__<<": libvlc_MediaFreed = "<<event->u.media_freed.md<<std::endl;
        break;
    case libvlc_MediaStateChanged:
        std::cout<<__func__<<":libvlc_MediaStateChanged = "<<event->u.media_state_changed.new_state<<std::endl;
        break;
    default:
        break;
    }
}

std::vector<libvlc_event_e> create_events()
{
    return {libvlc_MediaMetaChanged,
                libvlc_MediaSubItemAdded,
                libvlc_MediaDurationChanged,
                libvlc_MediaParsedChanged,
                libvlc_MediaFreed,
                libvlc_MediaStateChanged};
}

int main()
{
    libvlc_instance_t *inst = libvlc_new(0, nullptr);
    char const *location = "C:/Users/ssss/audio/audio.mp3";
    libvlc_media_t *vlc_media = libvlc_media_new_location(inst, location);
    libvlc_event_manager_t *vlc_events = libvlc_media_event_manager(vlc_media);

    for(libvlc_event_e const &event : create_events()){
        libvlc_event_attach(vlc_events, event, libvlc_callback, nullptr);
    }

    libvlc_media_add_option(vlc_media, "--sout='#transcode{acodec=s16l, ab=16, channels=1, samplerate=16000}:"
                                       "std{access=file, mux=wav, "
                                       "dst=\"audio.wav\"}'");

    std::this_thread::sleep_for(std::chrono::seconds(10));

    libvlc_media_release(vlc_media);
    libvlc_release(inst);
}

我得到的输出是

main libvlc debug: VLC media player - 3.0.9.2 Vetinari
main libvlc debug: Copyright © 1996-2020 the VideoLAN team
main libvlc debug: revision 3.0.9.2-0-gd4c1aefe4d
main libvlc debug: configured with ../extras/package/win32/../../../configure  '--enable-update-check' '--enable-lua' '--enable-faad' '--enable-flac' '--enable-theora' '--enable-avcodec' '--enable-merge-ffmpeg' '--enable-dca' '--enable-mpc' '--enable-libass' '--enable-schroedinger' '--enable-realrtsp' '--enable-live555' '--enable-dvdread' '--enable-shout' '--enable-goom' '--enable-caca' '--enable-qt' '--enable-skins2' '--enable-sse' '--enable-mmx' '--enable-libcddb' '--enable-zvbi' '--disable-telx' '--enable-nls' '--host=x86_64-w64-mingw32' '--with-breakpad=https://win.crashes.videolan.org' 'host_alias=x86_64-w64-mingw32' 'PKG_CONFIG_LIBDIR=/home/jenkins/workspace/vlc-release/windows/vlc-release-win32-x64/contrib/x86_64-w64-mingw32/lib/pkgconfig'
main libvlc debug: using multimedia timers as clock source
main libvlc debug:  min period: 1 ms, max period: 1000000 ms
main libvlc debug: searching plug-in modules
main libvlc debug: loading plugins cache file C:\vlc-3.0.9.2-win64\plugins\plugins.dat
main libvlc warning: cannot read C:\vlc\vlc-3.0.9.2-win64\plugins\plugins.dat: No such file or directory
main libvlc debug: recursively browsing `C:\vlc\vlc-3.0.9.2-win64\plugins'
main libvlc debug: plug-ins loaded: 494 modules
main logger debug: looking for logger module matching "any": 2 candidates
main logger debug: using logger module "console"
main libvlc debug: translation test: code is "C"
main keystore debug: looking for keystore module matching "memory": 3 candidates
main keystore debug: using keystore module "memory"
main libvlc debug: CPU has capabilities MMX MMXEXT SSE SSE2 SSE3 SSSE3 SSE4.1 SSE4.2 FPU 
libvlc_callback: libvlc_MediaFreed = 000001DBD602CC50
main libvlc debug: exiting
main libvlc debug: no exit handler
main libvlc debug: removing all interfaces
main keystore debug: removing module "memory"

我在文件夹中看不到任何生成的 audio.wav,我错过或做错了哪一步?谢谢

编辑:将参数传递给 libvlc_new

const char * const vlc_args[] = {
                  "--sout", 
   "#transcode{acodec=s16l,channels=2,samplerate=44100}:std{access=file,mux=wav,dst=\"C:/my_path/clip_0002.wav\"}",
    "C:/my_path/audio.wav"};
    libvlc_instance_t *inst = libvlc_new(3, vlc_args);

    std::this_thread::sleep_for(std::chrono::seconds(60));
    libvlc_release(inst);

它给我输出信息

main libvlc debug: exiting
main libvlc debug: no exit handler
main libvlc debug: removing all interfaces
main keystore debug: removing module "memory"

不知道为什么输出文件'audio.wav'从未在文件夹中生成

找到解决办法,你需要正确播放媒体和打开文件,为简单起见我在这个例子中使用"libvlc_media_new_path",如果你使用"libvlc_media_new_location",记得附加"file:///" 在位置之前并更改为本机分隔符。

#include "core/vlc_error.hpp"

#include <vlc/vlc.h>

#include <chrono>
#include <iostream>
#include <string>
#include <thread>
#include <vector>

#include <QString>

void libvlc_callback(libvlc_event_t const *event, void*)
{
    switch (event->type) {
    case libvlc_MediaMetaChanged:
        std::cout<<__func__<<": libvlc_MediaMetaChanged = "<<event->u.media_meta_changed.meta_type<<std::endl;
        break;
    case libvlc_MediaSubItemAdded:
        std::cout<<__func__<<": libvlc_MediaSubItemAdded = "<<event->u.media_subitem_added.new_child<<std::endl;
        break;
    case libvlc_MediaDurationChanged:
        std::cout<<__func__<<": libvlc_MediaDurationChanged = "
                <<event->u.media_duration_changed.new_duration<<std::endl;
        break;
    case libvlc_MediaParsedChanged:
        std::cout<<__func__<<": libvlc_MediaParsedChanged = "<<event->u.media_parsed_changed.new_status<<std::endl;
        break;
    case libvlc_MediaFreed:
        std::cout<<__func__<<": libvlc_MediaFreed = "<<event->u.media_freed.md<<std::endl;
        break;
    case libvlc_MediaStateChanged:
        std::cout<<__func__<<":libvlc_MediaStateChanged = "<<event->u.media_state_changed.new_state<<std::endl;
        break;
    default:
        break;
    }
}

std::vector<libvlc_event_e> create_events()
{
    return {libvlc_MediaMetaChanged,
                libvlc_MediaSubItemAdded,
                libvlc_MediaDurationChanged,
                libvlc_MediaParsedChanged,
                libvlc_MediaListEndReached,
                libvlc_MediaFreed,
                libvlc_MediaStateChanged};
}

int main()
{
    libvlc_instance_t *inst = libvlc_new(0, nullptr);
    char const *location = "clip_0002.wav";
    libvlc_media_t *vlc_media = libvlc_media_new_path(inst, location);
    libvlc_event_manager_t *vlc_events = libvlc_media_event_manager(vlc_media);

    for(libvlc_event_e const &event : create_events()){
        libvlc_event_attach(vlc_events, event, libvlc_callback, nullptr);
    }

    QString const cmd("transcode{acodec=s16l, ab=16, channels=1, samplerate=16000}:"
                      "std{access=file, mux=wav, "
                      "dst='audio.wav'}");
    QString config = ":sout=#duplicate{dst=display,dst=\"%1\"}";
    config = config.arg(cmd);
    std::cout<<"-------------------------"<<std::endl;
    std::cout<<config.toStdString()<<std::endl;
    libvlc_media_add_option(vlc_media, ":sout-all");
    qt_vlc::vlc_error::show_err_msg();
    libvlc_media_add_option(vlc_media, config.toUtf8().data());
    qt_vlc::vlc_error::show_err_msg();     

    libvlc_media_player_t *vlc_player = libvlc_media_player_new_from_media(vlc_media);
    libvlc_audio_set_mute(vlc_player, true);
    libvlc_media_player_play(vlc_player);

    while(1){
        qt_vlc::vlc_error::show_err_msg();
        if(libvlc_media_get_state(vlc_media) == libvlc_Ended){
            break;
        }
        std::cout<<"media state = "<<libvlc_media_get_state(vlc_media)<<std::endl;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }

    libvlc_media_player_release(vlc_player);
    libvlc_media_release(vlc_media);
    libvlc_release(inst);
}

您也可以通过此解决方案将视频转换为音频,问题是转换时会显示视频,找到隐藏视频的方法。