ラベル ffmpeg の投稿を表示しています。 すべての投稿を表示
ラベル ffmpeg の投稿を表示しています。 すべての投稿を表示

2022-02-27

FFmpegでPulseAudio入力の量子化ビット幅を設定する方法

FFmpegでPulseAudioの音声を録音する際、デフォルトでは16ビットになる。 24ビットや32ビットに設定するには、 -c:a オプションを使用する。

例えば、以下のようなコマンドで、32ビットで録音することができる。

-c:a pcm_s32le -f pulse -i alsa_input.device_name.analog-stereo -c pcm_s32le output.wav

なお、 -cオプションを使用した場合、中途半端に設定が変わるようで、左右のデータが混じったりと正しく動作しない。 ソースコードを追ったところ、pulse audioへはS16LEを要求し、受け取ったデータを -c で設定したフォーマットでそのまま処理するように見える。

2021-09-09

Rocket Lakeでvaapiを使用する方法

Fedora 34で、Intel第11世代のCore i7でvaapiを使用する方法の概略をメモしておく。

セットアップの概略

  1. rpmfusionをセットアップする。
  2. ffmpeg などをDNFでインストールする。
  3. libva libva-intel-driver などをDNFでインストールする。
  4. intel-media-driver をソースからビルドする。21.1.3では動作せず、21.2.3にしたら動作した。
    1. rpmfusionからsrpmをダウンロード
      dnf download --source intel-media-driver
    2. ダウンロードしたsrpmを展開
      rpm -Uvh intel-media-driver-21.1.3-1.fc34.src.rpm
    3. specファイルを編集
      vim rpmbuild/SPECS/intel-media-driver.spec
      Version, Source0, %changelog を編集した。
    4. ビルドしてインストールする
      rpmbuild -ba rpmbuild/SPECS/intel-media-driver-21.2.3.spec
      sudo rpm -Uvh /home/kamae/rpmbuild/RPMS/x86_64/intel-media-driver-21.2.3-1.fc34.x86_64.rpm

    使用

    LIBVA_DRIVERS_PATH=/usr/lib64/dri/ \
    LIBVA_DRIVER_NAME=iHD \
    ffmpeg \
    -vaapi_device /dev/dri/renderD128 -hwaccel vaapi -hwaccel_output_format vaapi -hwaccel_output_format vaapi \
    -i input.mkv -vf 'format=nv12|vaapi,hwupload,deinterlace_vaapi,scale_vaapi=w=1920:h=1080' -c:v h264_vaapi -c:a copy -y output.mp4
    

    これ以外に、ソースからビルドしたOBS Studioでも動作した。

2021-01-30

FFplay disappears when loosing focus

デュアルディスプレイ環境で、片方にffplayで動画を再生しもう一方で作業しようとすると、ffplayがフォーカスを失ったときにウィンドウが消えるという問題に遭遇した。

この原因は、SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSSというヒントが設定されているためで、これを無効にすればよい。

以下のようにffplay.cに1行加えることで、問題を解決できた。

diff --git a/fftools/ffplay.c b/fftools/ffplay.c
index 9ff0425163..2e3d7a18cc 100644
--- a/fftools/ffplay.c
+++ b/fftools/ffplay.c
@@ -3755,6 +3755,7 @@ int main(int argc, char **argv)
             flags |= SDL_WINDOW_RESIZABLE;
         window = SDL_CreateWindow(program_name, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, default_width, default_height, flags);
         SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
+        SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
         if (window) {
             renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
             if (!renderer) {

2020-12-22

動画ファイルのキーフレーム間隔を調べる方法

Stackoveflowのこの記事で、動画ファイル中のキーフレームの時刻を表示するサンプルが示されていた。 これを参考に、キーフレーム間隔を調べる方法をメモする。

入力ファイルをinput.mp4とすると、FFprobeとawkを使って以下のコマンドにより、キーフレーム間隔を調べることができる。

ffprobe -loglevel error -select_streams v:0 -show_entries packet=pts_time,flags -of csv=print_section=0 input.mp4 | awk -F',' '/K/ {print $1-prev; prev=$1}' | sort | uniq -c
出力は、間隔でソートし、それぞれの出現回数をuniqのオプション-cで表示する。

2020-11-03

SSHを通して遠隔にあるLinuxマシンのデスクトップ音声を聴く方法

はじめに

SSHでログインできるLinuxマシンのデスクトップ音声を聴く方法を説明する。 X11VNCを使うとデスクトップを操作することが可能だ。しかしながら、VNCには音声を転送する機能が付いていない。このようなとき、音声を圧縮してSSH経由で送ることで、やや遅延があるが、音声を一緒に聴くことができるようになる。

環境

接続先は、Pulse Audioが動いており、オーディオデバイスが接続されていることが必要である。 以下の手順は、遠隔ホストとしてScientific Linux 7を使用した。

手順

  1. まず、出力デバイスのモニターを確認する。最後に.monitorと名前が着いているものが出力デバイスのモニター (出力中の音を入力できる) である。
    $ LANG=C pactl list sources | grep Name
  2. 予め、無音の音声を再生しておく。
    $ ffplay -loglevel error -vn -nodisp -f s16le /dev/zero &
  3. SSHで接続した先でffmpegによりモニターをmp3に変換し、ローカルへパイプして、ffplayで再生する。
    $ input=alsa_output.usb-Burr-Brown_from_TI_USB_Audio_CODEC-00.analog-stereo.monitor # 上記で取得したモニターの名前
    $ ssh user@example.com ffmpeg -fflags nobuffer -flags low_delay -loglevel error -f pulse -ac 2 -i ${input} -c:a aac -f flv - | ffplay -fflags nobuffer -flags low_delay -nodisp -loglevel error -f flv -
ここで重要なのは、ffmpegとffplayそれぞれに-fflags nobuffer -flags low_delayを付けることだ。これらのオプションがなくても機能するが、段々と音声のバッファリングが増え、徐々に遅れが目立ち始める。

2018-10-28

PKG_CONFIG_PATHを使用したビルド

複数のバージョンのライブラリをインストールしたいなどの場合, バージョンごとにインストール先のディレクトリを分けることがある. その場合に, そのライブラリをリンクして別のソフトをビルドする方法をメモしておく.

ライブラリ (この例ではx264) のビルド・インストールをする. 以下の例では, /usr/local/x264/2018092の下にインストールする設定でビルド・インストールする.

$ mkdir b && cd b
$ ../configure --prefix=/usr/local/x264/20180923
$ make
$ sudo make install

上記のライブラリをリンクするソフト (この例ではffmpeg) のビルド・インストールをする.

$ mkdir b && cd b
$ PKG_CONFIG_PATH=/usr/local/x264/20180923/lib/pkgconfig: ../configure --enable-libx264 --prefix=/usr/local/ffmpeg/4.0.git
$ make
$ sudo make install
例で使用したffmpegでは --extra-cflags--extra-ldflagsというオプションでx264のパスを設定することもできるが, pkg-configを使用したほうが, よりライブラリ開発者の意図した設定でビルドすることができる.

あとは, 以下のようなラッパーを用意しておく.

#! /bin/bash
export LD_LIBRARY_PATH=/usr/local/ffmpeg/4.0.git/lib:/usr/local/x264/20180923/lib:
exec /usr/local/ffmpeg/4.0.git/bin/"$(basename "$0")" "$@"

2014-07-29

FFmpeg にて HPF を使用する

ある音源を聞いていたら電源のノイズが音にのっているように感じたので, HPF (ハイパスフィルタ) を使用してみた.
ffmpeg -i input.mp3 -filter_complex highpass=f=500 output.mp3
FFmpeg のフィルタには, LPF (ローパスフィルタ) や BPF (バンドパスフィルタ) もあるようだ.

2014-01-04

FFplayで出力ディバイスをALSAに設定

2個の環境変数を以下のように設定する. (hw:1の部分にサウンドカードの番号をいれる. alsamixer上でF6キーを押すと一覧がでる.)
export SDL_AUDIODRIVER=alsa
export AUDIODEV=hw:1
FFplayではSDLを使用して音声を出力するので, 環境変数にてSDLに出力ディバイスを設定する.

例えば, 以下のようにffplayを実行する.

env SDL_AUDIODRIVER=alsa AUDIODEV=hw:1 ffplay ...

参考

  • ALSA flags in ffplay
  • 2013-12-23

    MMSストリームをFFmpegで保存

    以前の投稿と似ているが, FFmpeg で MMS ストリームを取得・保存する方法を説明する.
    ffmpeg -i mmst://media.example.org/stream1 -codec copy output.wmv
    

    上記のように, mmst://...と記述する. FFmpegでは, MMSの扱いとして2種類 (over TCP と over HTTP) 用意されている. mmst と書くと over TCP, mmsh と書くと over HTTP になる. 単に mms://... と書くと動作しない.

    コーデックとして -codec copy を選ぶと, 変換は行わずにそのまま保存することができる. (まったく同じストリームになるわけではなく, ストリーム番号が変わったりすることもあるようだ.)
    -codec copy」のかわりに「-codec:v copy」「-codec:a copy」と書くとビデオ・オーディオのみ変換しないように指定することもできる.

    OpenLP + FFmpeg でテキストをオーバレイ

    OpenLP には, 遠隔操作用プラグインがあり, JSONによって表示中のテキストを取得することができる. OpenLP のテキストを FFmpeg でオーバレイするためのスクリプトを作成した.
    #! /bin/env python
    # vi: set expandtab sw=4 ts=4:
    
    server='http://192.168.xx.xx:4316'
    out='/dev/shm/live.txt'
    tmp='/dev/shm/live.txt.tmp'
    
    def get(url):
        import urllib2
        import json
        s = urllib2.urlopen(server+url).read()
        j = json.loads(s)
        return j
    
    def text():
        t = get('/api/controller/live/text')
        ss = t[u'results'][u'slides']
        for s in ss:
            text = s[u'text']
            selected= s[u'selected']
            if selected:
                return text
    
    def update(s):
        import os
        if s==u'':
            s = u'\n'
        open(tmp, 'w').write(s.encode('utf_8'))
        os.rename(tmp, out)
    
    pp = False
    
    while True:
        try:
            p = get('/api/poll')
            if p!=pp:
                t = text()
                pp = p
                print p
                print t.encode('utf_8')
                update(t)
        except:
            update(u'')
            import time
            time.sleep(10)
        import time
        time.sleep(1)
    
    これを実行した上で, FFmpeg を以下のように起動する.
    /usr/local/bin/ffmpeg -loglevel warning -f video4linux2 -i /dev/video0 -f alsa -i hw:0 \
    -vf drawtext='fontfile=/usr/share/fonts/ipa-gothic/ipag.ttf:textfile=/dev/shm/live.txt:fontsize=24:fontcolor=black:box=1:y=12:x=(W-tw)/2:reload=1:boxcolor=white@0.5' \
    -vb 2048k -ab 64 -f mpegts -vcodec mpeg2video -pix_fmt yuv420p -b:v 3M -acodec mp2 -ab 128k -ar 44100 -ac 2 -aspect 4:3 - | \
    /usr/local/bin/ffmpeg -loglevel warning -f mpegts -i - http://127.0.0.1:9999/feed1.ffm
    
    なぜか feed1.ffmを出力にするとフィルタが機能しなかったので, パイプを使った.

    FFserver + MediaTomb でビエラに映像を配信

    PCに接続したキャプチャデバイスでリアルタイムに映像を取り込み, パナソニックのテレビ (Viera) に映像を配信する方法をメモする.

    FFmpeg はキャプチャデバイスから映像を取り込んだり様々な映像フォーマットに変換することができる. FFmpeg に付属する FFserver で HTTP 形式での映像配信は可能. 残念なことに FFserver は DLNA には対応していないので, DLNA での配信は MediaTomb に任せることにする. ここでは主に FFserver から MediaTomb にストリームを渡す部分を説明する.
    FFmpeg でデータの変換, FFserver でストリームを配信可能にし, MediaTomb で配信をする.

    FFserverの設定

    FFserver の設定の中に Launch を書いておくことで, FFmpeg を呼び出すことが可能.
    フォーマットやコーデックを下記のように指定すると, Viera で再生することができる.
    Port 9999
    RTSPPort 9990
    BindAddress 0.0.0.0
    MaxClients 1000
    MaxBandwidth 100000
    CustomLog -
    
    <Feed feed1.ffm>
    File /dev/shm/feed1.ffm
    FileMaxSize 100M
    Launch /usr/local/bin/ffmpeg -f video4linux2 -i /dev/video0 -f alsa -i hw:0
    </Feed>
    
    <Stream mpegts.mpeg>
    Feed feed1.ffm
    Format mpegts
    
    VideoCodec mpeg2video
    VideoBitRate 2048
    VideoFrameRate 29.97
    VideoSize 720x480
    VideoGopSize 12
    PixelFormat yuv420p
    
    AudioCodec mp2
    AudioBitRate 64
    AudioChannels 2
    AudioSampleRate 44100
    </Stream>
    
    <Stream teststat.html>
    Format status
    </Stream>
    

    MediaTomb config.xml

    MediaTomb から CURL を呼び出し, FFmpeg の配信するストリームを MediaTomb に渡す.
    CURLを呼び出すため, まずはシェルスクリプトを実行可能にする. 拡張子.shvideo/scriptというMIMEtypeにマップする. video/scriptは, bashというプロファイルでトランスコード. 最後に, プロファイルbashを定義する. -xオプションを付けておくことで, どのようなスクリプトが実行されたのか分かり, デバッグに役立つ.
    ...
            <map from="sh" to="video/script"/>
    ...
              <transcode mimetype="video/script" using="bash"/>
    ...
          <profile name="bash" enabled="yes" type="external">
            <mimetype>video/mpeg</mimetype>
            <accept-url>yes</accept-url>
            <first-resource>yes</first-resource>
            <accept-ogg-theora>yes</accept-ogg-theora>
                    <agent command="/bin/bash" arguments="-x %in %out"/>
            <buffer size="14400000" chunk-size="512000" fill-size="120000"/>
          </profile>
    ...
    
    CURLを実行するスクリプトを用意し, MediaTomb に追加する. 引数$1%outになるので, これへ出力する. 実際には名前付きパイプになっているようだ.
    #! /bin/bash
    exec curl -s -o "$1" http://localhost:9999/mpegts.mpeg
    

    Vieraでの操作

    操作方法がやや複雑なので, 以下に手順を書いておく.
  • リモコンのボタンビエラリンクを押す.
  • お部屋ジャンプリンクを選び, 決定を押す.
  • MediaTombを選び, 決定を押す.
  • Videoを選び, 決定を押す.
  • All Videoを選び, 決定を押す.
  • stream1.shを選び, 決定を押す.
  • を選び, 決定を押す. 当然のことながら, 発売時期などによって対応状況や操作方法が異なるので, 型番を調べて記載する予定である.

    お部屋ジャンプに対応しているテレビを以下に挙げる.

  • 2013-12-22

    FFmpeg で動画にテキストをリアルアイムでオーバレイ

    FFmpeg に, drawtext というビデオフィルタがあり, テキストを動画にオーバレイすることができる. 色々と便利な機能もついている.
    1. 文字部分のボックスを塗りつぶす.
      背景の色によっては文字が見えにくくなることもあるが, このような場合はボックス機能を使えば良い.
      box=1:boxcolor=black
      ボックスを半透明にする場合は, @の後に数字を書く.
      box=1:boxcolor=black@0.5
    2. フォントの指定が可能.
      日本語のフォントも指定可能. 文字の色や大きさも指定できる.
      fontfile=/usr/share/fonts/ipa-gothic/ipag.ttf:fontsize=48:fontcolor=white
    3. 文字列の展開が可能
      1. 時刻
    4. 影をつけることが可能
    5. ファイルから読み込み
      reload=1をつけると, 1フレーム毎にファイルを読み込む.
      textfile=tmp.txt:reload=1
      なお, ファイルを更新するときには, 以下のようにファイルの更新がアトミックに行われるようにすればよい.
    6. 予め別のファイルで新しいデータを作成.
      echo '新しいテキスト' >tmp1.txt
    7. ムーブでファイルを更新.
      mv tmp1.txt tmp.txt
      もし頻繁に書き換えるなら, /dev/shm/下などのtmpfs上に作成するのが良いだろう.
    8. 文字の表示位置
      数式で表示位置を指定可能. センタリグするには, 以下の式:
      x=(W-tw)/2

    意外といろいろな機能がついていることが分かった. OpenLP と組み合わせて使おうと思う.

    2013-11-19

    ffmpeg で動画を切り取り

    FFmpeg にて開始時刻・終了時間をしていして動画を切り取る方法をメモする.
    $ ffmpeg -ss 開始時刻 -t 時間 -i 入力 -codec copy 出力
    
    -ssにて開始する時刻を指定できる. -tで, 出力する時間 (終了時刻-開始時刻) を指定できる. -codec copyで, デコード・エンコードの処理をせずにストリームをコピーする.

    X/Y軸方向に切り取るには, cropというフィルターを使用する.

    $ ffmpeg -i 入力 -vf 'crop=W:H:X:Y' -vb 1600k -ab 64k 出力
    

    参考にしたサイト

    2012-10-20

    FFmpeg

    FFmpeg は, フリーの映像・音声処理ツールである. Linux 上でも使用することができるが, ビルド方法がやや特殊であるため, ここに書いておく.
    1. ソースを取得する.
      $ git clone git://source.ffmpeg.org/ffmpeg
      $ cd ffmpeg
    2. ビルドする. configure の際に, nonfree を有効にすると, フリーでない (再頒布できない) バイナリが生成される. 個人で使用する分には, nonfree が良いだろう. その他, 色々とオプションをつけておく.
      $ ./configure --enable-nonfree --enable-gpl --enable-version3 --enable-libmp3lame
      $ make
    3. インストールする. プログラムとマニュアルだけをインストールする場合は, install ではなく, install-progs ルールを使用する.
      $ sudo make install-progs

    RHELでは, 以下のパッケージを予めインストールしておく.

    • lame-devel, lame-libs, rpmfusion.
    • yasm, epel.
    • ...