libVLC

VLCのライブラリです。

導入

ライセンス

libVLCのライセンスはLGPLですが、モジュールによってはGPLv2やそれ以降のものもあります。May I redistribute libVLC in my application? - Frequently Asked Questions - VideoLAN Wiki

個々のモジュールのライセンスはVLCのソースコードmodulesフォルダ以下にあるソースのコメント部で確認でき、そこに「under the terms of the GNU General Public License」の記述があるならばGPLです。plugins license - The VideoLAN Forums

使用例

Visual Studioから使用する場合について考えます。

  1. Index of /pub/videolan/vlc/からVLC Playerのバイナリを含むファイルをダウンロードし、展開する。
  2. Visual Studioで、新規にC++のプロジェクトを作成する。
    1. 作業ディレクトリに、展開したVLCに含まれるlibvlc.dlllibvlccore.dllそれにpluginsフォルダをコピーする。
      • プラグインを適切に配置しないと「core libvlc error: No plugins found! Check your VLC installation.」と通知されます。
    2. プロパティの[C/C++]の[追加のインクルード ディレクトリ]に、VLCのsdk\includeへのパスを追加する。
    3. プロパティの[リンカー]の[追加の依存ファイル]に、VLCのsdk\lib\libvlc.libを追加する。
  3. 動作確認用の音声ファイルを用意する。
  4. 以下のコードの音声ファイルのパスを修正した上で、動作を確認する。
#include <windows.h>

#include <stdio.h>
#include <stdlib.h>
#include <vlc/vlc.h>

int main()
{
    /* VLCエンジンを読み込む */
    libvlc_instance_t* instance = libvlc_new(0, NULL);

    /* 新しい項目を作成する */
    libvlc_media_t* media = libvlc_media_new_path(instance, "path/sample.mp3"); // ファイルパス (相対パス)
    // media = libvlc_media_new_path(instance, "C:\\path/sample.mp3");          // ファイルパス (絶対パス)
    // media = libvlc_media_new_location(instance, "http://example.com/sample.mp3"); // URL

    /* メディアプレーヤーの再生環境を作成する */
    libvlc_media_player_t* media_player = libvlc_media_player_new_from_media(media);

    /* メディアを保持する必要がなくなったため、メディアの参照カウントを減少させる */
    libvlc_media_release(media);

    /* メディアプレーヤーを再生する */
    libvlc_media_player_play(media_player);

    /* 待機する */
    while (libvlc_state_t::libvlc_Ended != libvlc_media_player_get_state(media_player))
    {
        Sleep(10);
    }

    /* 再生を止める */
    libvlc_media_player_stop(media_player);

    /* メディアプレーヤーを解放する */
    libvlc_media_player_release(media_player);

    libvlc_release(instance);

    return 0;
}
LibVLC Tutorial - VideoLAN Wiki

コンパイル時に「error C2065: 'libvlc_media_read_cb': 定義されていない識別子です。」として失敗するときには、vlc.hの読み込み前に

typedef SSIZE_T ssize_t;

としてSSIZE_Tを宣言します。 Problem when including "vlc.h" file to c++ win32 - The VideoLAN Forums c - Why ssize_t in Visual Studio 2010 is defined as unsigned? - Stack Overflow

再生するのが動画ならば、再生前にウィンドウ ハンドルをメディアプレーヤーに設定し、再生を開始させるために制御を戻します。

libvlc_media_player_set_hwnd(media_player, hWnd);

/* メディアプレーヤーを再生する */
libvlc_media_player_play(media_player);

LibVLC core

libvlc_new

LibVLCのインスタンスを作成し初期化できます。

libvlc_instance_t* libvlc_new(
    int argc,               // 引数の数
    const char *const *argv // 引数のリスト (VLC media playerへ渡すコマンドと同じ)
    );
libvlc_new() - VLC: LibVLC core

LibVLC video controls

libvlc_video_take_snapshot

int libvlc_video_take_snapshot(
    libvlc_media_player_t *p_mi, // 
    unsigned num,                // ビデオ出力の数
    const char *psz_filepath,    // スクリーンショットを保存するパス
    unsigned int i_width,        // 
    unsigned int i_height        // 
    );
libvlc_video_take_snapshot() - VLC: LibVLC video controls

psz_filepathでフォルダを指定した場合には、ファイル名は日時となります。

libvlc_instance_t* pInstance = libvlc_new(0, NULL);
libvlc_media_t*	pMedia = libvlc_media_new_path(pInstance, "C:\\sampl.mp4");

libvlc_media_player_t* pMediaPlayer = libvlc_media_player_new_from_media(pMedia);
libvlc_media_release(pMedia);

libvlc_media_player_play(pMediaPlayer);
Sleep(500); // 再生の開始を待つ
libvlc_media_player_set_position(pMediaPlayer, 0.5);
Sleep(500); // シークの完了を待つ

int result = libvlc_video_take_snapshot(pMediaPlayer, 0, "C:\\", 0, 0);

libvlc_media_player_stop(pMediaPlayer);
libvlc_media_player_release(pMediaPlayer);
libvlc_release(pInstance);
git.videolan.org Git - vlc.git/blob - doc/libvlc/vlc-thumb.c

Stream to memory (smem)

VLCによって読み込まれた映像と音声のデータを処理できます。

#include <windows.h>

#include <stdio.h>
#include <stdlib.h>
#include <vlc/vlc.h>


uint8_t* audioBuffer = NULL;
uint8_t* videoBuffer = NULL;
unsigned int audioBufferSize = 0;
unsigned int videoBufferSize = 0;

unsigned int videoWidth = 0;
unsigned int videoHeight = 0;


void AudioPrerenderCallback(void* pUserData, uint8_t** ppPcmBuffer, size_t size)
{
    // TODO: ミューテックス (mutex) をロックする

    // バッファが確保されていない、もしくはサイズが不足するならば確保する
    if (!audioBuffer || audioBufferSize < size)
    {
        if (audioBuffer) free(audioBuffer);

        audioBuffer = (uint8_t*)malloc(size);
        audioBufferSize = size;
    }

    *ppPcmBuffer = audioBuffer;
}

void AudioPostrenderCallback(void* pUserData, uint8_t* pPcmBuffer, unsigned int channels, unsigned int rate, unsigned int nbSamples, unsigned int bitsPerSample, size_t size, int64_t pts)
{
    // TODO: ミューテックス (mutex) をアンロックする

    // pPcmBufferからオーディオデータのサンプルを、size数だけ取得できる

    switch (bitsPerSample)
    {
    case 8:
        break;
    case 16:
        for (size_t i = 0; i < size; i += 2)
        {
            int16_t data = ((int16_t)pPcmBuffer[i + 1] << 8) | pPcmBuffer[i];
        }
        break;
    }
}


void VideoPrerenderCallback(void* pUserData, uint8_t** ppPixelBuffer, size_t size)
{
    // TODO: ロック

    if (!videoBuffer || videoBufferSize < size)
    {
        if (videoBuffer) free(videoBuffer);

        videoBuffer = (uint8_t *)malloc(size);
        videoBufferSize = size;
    }
    *ppPixelBuffer = videoBuffer;
}

void VideoPostrenderCallback(void* pUserData, uint8_t* pPixelBuffer, int width, int height, int pixelPitch, size_t size, int64_t pts)
{
    // TODO: アンロック

    // libvlc_MediaParsedChangedイベントで取得したサイズに修正する
    width = videoWidth ? videoWidth : width;
    height = videoHeight ? videoHeight : height;

    // pPixelBufferからビデオのスナップショットを、width × heightの大きさで取得できる
}

void HandleEvents(const libvlc_event_t* pEvent, void* pUserData)
{
    switch (pEvent->type)
    {
    case libvlc_MediaParsedChanged:
    {
        libvlc_media_t* pMedia = (libvlc_media_t*)pUserData;
        libvlc_media_track_t** ppTracks = NULL;
        unsigned int trackCount = libvlc_media_tracks_get(pMedia, &ppTracks);

        for (size_t i = 0; i < trackCount; i++)
        {
            if (ppTracks[i]->i_type == libvlc_track_video)
            {
                libvlc_video_track_t* pVideo = ppTracks[i]->video;

                videoWidth = pVideo->i_width;
                videoHeight = pVideo->i_height;
            }
        }
    }
    }
}

int main()
{
    const char* const args[] = {
        "--ignore-config",
        "--verbose=2" // ログ出力レベル
    };

    libvlc_instance_t* pInstance = libvlc_new(sizeof(args) / sizeof(args[0]), args);
    libvlc_media_t* pMedia = libvlc_media_new_path(pInstance, "C:\\sample.avi");

    char smemOptions[256];
    sprintf(
        smemOptions,
        ":sout=#transcode{vcodec=RV32,acodec=s16l}"
        ":smem{"
        "audio-prerender-callback=%lld,"
        "audio-postrender-callback=%lld,"
        "video-prerender-callback=%lld,"
        "video-postrender-callback=%lld,"
        "audio-data=%lld,"
        "video-data=%lld}",
        (long long int)(intptr_t)(void*)&AudioPrerenderCallback,
        (long long int)(intptr_t)(void*)&AudioPostrenderCallback,
        (long long int)(intptr_t)(void*)&VideoPrerenderCallback,
        (long long int)(intptr_t)(void*)&VideoPostrenderCallback,
        (long long int)(intptr_t)(void*)pMedia,
        (long long int)(intptr_t)(void*)pMedia
    );

    libvlc_media_add_option(pMedia, smemOptions);

    // イベントに登録
    libvlc_event_manager_t* pEventManager = libvlc_media_event_manager(pMedia);
    libvlc_event_attach(pEventManager, libvlc_MediaParsedChanged, HandleEvents, pMedia);

    // メディアプレーヤーを作成
    libvlc_media_player_t* pMediaPlayer = libvlc_media_player_new(pInstance);
    libvlc_media_player_set_media(pMediaPlayer, pMedia);
    libvlc_media_player_play(pMediaPlayer);

    libvlc_media_release(pMedia);

    libvlc_state_t state;
    while (libvlc_state_t::libvlc_Ended != (state = libvlc_media_player_get_state(pMediaPlayer)))
    {
        Sleep(10);
    }

    libvlc_media_player_stop(pMediaPlayer);
    libvlc_media_player_release(pMediaPlayer);
    libvlc_release(pInstance);

    if (audioBuffer) free(audioBuffer);

    return 0;
}
Using libvlc to extract raw frames and audio from media via smem · GitHub GitHub - aleksas/libvlc-stream-grabber: Access video frames and audio sample using libvlc smem module.

codec

   
vcodec FourCC
acodec TwoCC

Modules (plugins / プラグイン)

モジュール 能力
audio filter An audio filter, like an equalizer
audio mixer An audio channel mixer, like a downmixer
audio output An audio output, like Windows DirectX audio output
decoder A codec decoder, like theora
demux A demuxer, to open a file format, like mkv
encoder A codec encoder, like x264
interface An interface, like the Qt interface
meta reader A meta reader, to read metadata
packetizer A packetizer
playlist export A module to write playlist, like .m3u
services_discovery A module to get extra content from your computer or the network, like Upnp, DLNA
sout access An access for the streaming
sout mux A muxer when streaming and encoding
stream_filter A stream filter
text renderer A way to display subtitles and other text on top of the video
video filter A video filter, like contrast adjusting
visualization2 A visualizer, to create videos from the music
vout display A video output, to display videos like Direct3D or Xv
Major Capabilities of Modules - Documentation:VLC Modules Loading - VideoLAN Wiki
複数の技術系サイトから、まとめて検索