MachiKania type PUで動画再生、その3
2025年5月24日
MachiKania type PUでの動画再生について。この記事では、音声付き動画の再生方法と、使用するWAVファイルの作成方法について述べる。

まず、PLAYAVIクラスで音声付きで再生することができるのは、15 fpsの動画だけである。また、AVIファイルは、音声データーを含まないことが前提だ。従って、動画の再生と同時に音声も再生するには、別途音声ファイルを準備する必要がある。PLAYAVIクラスでは、音声ファイルとしてWAVファイルを扱うので、これをAVIファイルとは別に用意する。
ここで使用するWAVファイルは、次の条件を満たしている必要がある。
1.音声データーは、圧縮なしのPCM
2.8ビットモノラル
3.サンプリングレートは、およそ15825 Hz
ここでは、このようなwavファイルを作成する方法の例について述べる。mp4ファイルから音声を抽出し、aviファイルに変換する方法を例示する。次のツールを用いる。
・FFmpeg:MP4ファイルをWAVファイルに変換するために用いる
MP4ファイルを準備
まず、元となるMP4ファイルを準備する。この記事の説明では、以下のwebサイトからダウンロードした。「NHKクリエイティブ・ライブラリー」著作の、フリー素材だ。
https://www2.nhk.or.jp/archives/movies/?id=D0002030736_00000
このMP4ファイルは、29.97 fps(1秒間に29.97フレーム)で1分39秒の動画である。ここでは、最終的に15 fpsのAVIファイルと、別にWAVファイルに変換する例を挙げる。また、動画の初めの30秒だけ使用する。
AVIファイル作成
AVIファイルの作成方法は、「その2」で述べた方法と同じである。ただし、最初の30秒だけ使うため、FFmpegを使う時のパラメーターに「-t 30」を加える。その他は、同様に進める。ここでは、最終的なAVIファイルを、「crick15.avi」として保存する。
WAVファイルのサンプリングレートの算出
ここで使うWAVファイルのサンプリングレートの値は、少し複雑だ。最初に述べた「15825 Hz」というサンプリングレートは、元のmp4動画のサンプリングレートが、ぴったり 30 fps の場合である(30*1055/2)。ここで使うmp4動画はサンプリングレートが29.97 fps なので、微調整が必要である。
この、29.97 という値は、正確には 30000/1001 なのだが、この値は、FFmpegに含まれている「ffprobe」によって調べることができる。
この例の場合、作成するWAVファイルのサンプルレートは、次のように計算する
15825 * (30000/1001) / 30 = 15809.190809...
サンプリングレートは整数値で設定する必要があるから、15809 Hzを使う。ただし、0.190809...(191/1001)の誤差があるので、それについては後で考察する。
WAVファイルの作成
サンプリングレートが確定したら、WAVファイルを作成する。FFmpegを利用し、一般的には次のように実行する。
ただし、「input.mp4」は任意のmp4ファイル名、「result.wav」は任意の出力wavファイル名。
ここの例では、「最初の31秒だけ抽出する」ためと「音量を上げる」ために、それぞれ「-t 31」と「-af "volume=32, dynaudnorm, alimiter=limit=0.9"」のパラメーターを追加し、上の計算通りサンプリング周波数を15809 Hzとするために「-ar 15809」として、次のコマンドを実行した。
いよいよ再生
必要なAVI、WAVの両方のファイルがそろったので、MachiKania type PUで再生する。RP2350搭載のRaspberry Pi Pico 2を使う。BASICファイルは、次の例のようにする。
音声と映像のずれの修正
元のmp4ファイルのサンプリングレートが、ぴったり 30 fps の場合、ここで述べた方法で動画再生しても理論的に音と映像がずれることはない(WAVファイルは、15825 Hzで作成)。しかし、元のmp4ファイルのサンプリングレートが29.97 fpsの場合などは、長く再生していると音と映像が少しずつずれてくる。
元のmp4ファイルのサンプリングレートが29.97 fps (30000/1001)の場合、本当ならサンプリングレートを
15809.190809190809190809190809...
でWAVファイルを作成しないといけないところ、15809 Hzで作成することになる。0..190809...(191/1001) Hz分のずれがある。3分の動画ならおよそ0.002秒、30分の動画ならおよそ0.02秒のずれだからほとんど気が付かないレベルだが、2時間の動画なら0.087秒ずれる(音声が遅れる)ので、気になるかもしれない。
そこで、こういった場合は再生中に音声再生位置を微調整する。画像を 1001 x 15 フレームだけ再生したときに 音声データーが191 ビットずれる計算だ。なので、BASICプログラムのメインループを次のようにすればよい。
もう一つの方法は、動画を15分ぐらいずつのものに分割しておき、それらを順次再生する方法だ。ファイルサイズが4 GBまでという制限があるFAT32ファイルシステムでは、336x216ピクセルサイズの動画はおよそ60分までしか対応できないので、長い動画を再生したいときはこちらのやり方の方が現実的かもしれない。この場合、上で述べた「MOVEWAVPOINTER」メソッドによる微修正は必要ない。

まず、PLAYAVIクラスで音声付きで再生することができるのは、15 fpsの動画だけである。また、AVIファイルは、音声データーを含まないことが前提だ。従って、動画の再生と同時に音声も再生するには、別途音声ファイルを準備する必要がある。PLAYAVIクラスでは、音声ファイルとしてWAVファイルを扱うので、これをAVIファイルとは別に用意する。
ここで使用するWAVファイルは、次の条件を満たしている必要がある。
1.音声データーは、圧縮なしのPCM
2.8ビットモノラル
3.サンプリングレートは、およそ15825 Hz
ここでは、このようなwavファイルを作成する方法の例について述べる。mp4ファイルから音声を抽出し、aviファイルに変換する方法を例示する。次のツールを用いる。
・FFmpeg:MP4ファイルをWAVファイルに変換するために用いる
MP4ファイルを準備
まず、元となるMP4ファイルを準備する。この記事の説明では、以下のwebサイトからダウンロードした。「NHKクリエイティブ・ライブラリー」著作の、フリー素材だ。
https://www2.nhk.or.jp/archives/movies/?id=D0002030736_00000
このMP4ファイルは、29.97 fps(1秒間に29.97フレーム)で1分39秒の動画である。ここでは、最終的に15 fpsのAVIファイルと、別にWAVファイルに変換する例を挙げる。また、動画の初めの30秒だけ使用する。
AVIファイル作成
AVIファイルの作成方法は、「その2」で述べた方法と同じである。ただし、最初の30秒だけ使うため、FFmpegを使う時のパラメーターに「-t 30」を加える。その他は、同様に進める。ここでは、最終的なAVIファイルを、「crick15.avi」として保存する。
WAVファイルのサンプリングレートの算出
ここで使うWAVファイルのサンプリングレートの値は、少し複雑だ。最初に述べた「15825 Hz」というサンプリングレートは、元のmp4動画のサンプリングレートが、ぴったり 30 fps の場合である(30*1055/2)。ここで使うmp4動画はサンプリングレートが29.97 fps なので、微調整が必要である。
この、29.97 という値は、正確には 30000/1001 なのだが、この値は、FFmpegに含まれている「ffprobe」によって調べることができる。
ffprobe -v error -select_streams v:0 -show_entries stream=r_frame_rate input.mp4ただし、「input.mp4」は任意のmp4ファイル。
この例の場合、作成するWAVファイルのサンプルレートは、次のように計算する
15825 * (30000/1001) / 30 = 15809.190809...
サンプリングレートは整数値で設定する必要があるから、15809 Hzを使う。ただし、0.190809...(191/1001)の誤差があるので、それについては後で考察する。
WAVファイルの作成
サンプリングレートが確定したら、WAVファイルを作成する。FFmpegを利用し、一般的には次のように実行する。
ffmpeg -i input.mp4 -ac 1 -ar 15825 -f wav -acodec pcm_u8 -t 31 result.wav
ただし、「input.mp4」は任意のmp4ファイル名、「result.wav」は任意の出力wavファイル名。
ここの例では、「最初の31秒だけ抽出する」ためと「音量を上げる」ために、それぞれ「-t 31」と「-af "volume=32, dynaudnorm, alimiter=limit=0.9"」のパラメーターを追加し、上の計算通りサンプリング周波数を15809 Hzとするために「-ar 15809」として、次のコマンドを実行した。
ffmpeg -i D0002030736_00000_V_000.mp4 -ac 1 -ar 15809 -f wav -acodec pcm_u8 -t 31 -af "volume=32, dynaudnorm, alimiter=limit=0.9" crick15.wav
いよいよ再生
必要なAVI、WAVの両方のファイルがそろったので、MachiKania type PUで再生する。RP2350搭載のRaspberry Pi Pico 2を使う。BASICファイルは、次の例のようにする。
useclass PLAYAVI cls system 51,15 system 50,315000000 system 57, 40000000 a=new(PLAYAVI,"crick15.avi") a.SETWAVE("crick15.wav") do wait 1 loop while a.play() end
音声と映像のずれの修正
元のmp4ファイルのサンプリングレートが、ぴったり 30 fps の場合、ここで述べた方法で動画再生しても理論的に音と映像がずれることはない(WAVファイルは、15825 Hzで作成)。しかし、元のmp4ファイルのサンプリングレートが29.97 fpsの場合などは、長く再生していると音と映像が少しずつずれてくる。
元のmp4ファイルのサンプリングレートが29.97 fps (30000/1001)の場合、本当ならサンプリングレートを
15809.190809190809190809190809...
でWAVファイルを作成しないといけないところ、15809 Hzで作成することになる。0..190809...(191/1001) Hz分のずれがある。3分の動画ならおよそ0.002秒、30分の動画ならおよそ0.02秒のずれだからほとんど気が付かないレベルだが、2時間の動画なら0.087秒ずれる(音声が遅れる)ので、気になるかもしれない。
そこで、こういった場合は再生中に音声再生位置を微調整する。画像を 1001 x 15 フレームだけ再生したときに 音声データーが191 ビットずれる計算だ。なので、BASICプログラムのメインループを次のようにすればよい。
w=15015 do w=w-1 if 0=w then w=15015 a.MOVEWAVPOINTER(191) endif wait 1 loop while a.play()
もう一つの方法は、動画を15分ぐらいずつのものに分割しておき、それらを順次再生する方法だ。ファイルサイズが4 GBまでという制限があるFAT32ファイルシステムでは、336x216ピクセルサイズの動画はおよそ60分までしか対応できないので、長い動画を再生したいときはこちらのやり方の方が現実的かもしれない。この場合、上で述べた「MOVEWAVPOINTER」メソッドによる微修正は必要ない。