はじめに
PowerPoint のオーディオ録音機能を用いて作成した pptx や ppsx は、ファイルサイズが結構大きめになります。これを手軽に小さくするための、ffmpeg を用いた簡単なスクリプトを書いてみます。
こちらの GitHubに、Windows用のバッチファイルと Mac用の bash のシェルスクリプトを、使用方法とともにまとめておきます。
遠隔オンライン授業
自宅にいながらの遠隔オンライン授業では、リアルタイム型の講義配信だけだと、受け手(学生)と送り手(教員)の通信状況(機器や電波状況、通信プラン、家族の利用時間の重複)、より広域なネットワーク帯域の制約、さらには遠隔会議サービスの提供側のリソースがあり、授業中に配信が不安定になることも考えらます。
そこで、様々な教育機関では、オンデマンド型を併用した授業方法が検討されています。授業資料の配布方法としては、動画を YouTube などのストリーミングサーバーへ上げる、PDF資料や、講義音声付き PowerPoint を学内のLMS (Learning Management System) サーバーや学外のクラウドサービスで共有するなど、様々な方法があります。
しかし、このうち音声付き PowerPoint のファイルサイズは意外と大きく、ストレージサーバーの容量を圧迫したり、アップロードのサイズ制限を受けたりします。ここではこのファイルサイズの圧縮を試みます。
音声付き PowerPoint スライド
音声付き PowerPoint は、PowerPoint の元々の機能で作成可能です。たとえば以下のステップで自動再生ファイルができます。
- 各ページで「挿入 > 録音 > オーディオの録音」を使って録音
- 各ページで、挿入されたスピーカーアイコンを選択
- 「再生 > 開始: 自動」を選択
- 「再生 > スライドショーを実行中にサウンドのアイコンを隠す」にチェック
- 「スライドショー」の設定
- ポインタの動きなどもさらに記録するなら「ナレーションの再生」にチェック
- 自動再生するなら「タイミングを使用」にチェック
- スライドショーの記録」>「先頭から記録」>「記録アイコン」
- 音声が自動再生されるので、授業の流れでスライドを進めながら記録
- pptx や ppsx(配布用)で保存
1まで終わってから以下の圧縮を行ってもよいですし、5まで終わってからでもOKです。
音声付きスライドの圧縮(手動)
pptx や ppsx は zip ファイルですが、その中にある media というフォルダに m4a 形式のオーディオが格納されます。
そのため、手動でやるなら以下の手順になります。ビットレートの変更には ffmpeg を使うことにします。また、オーディオは音声であることを前提として、元は 170kbps 以上あるようですが、これを 64kbps に落としてみます。
- いったんファイル名の pptx や ppsx を zip に変更します。
- zipを展開します。
- ppt/media/以下の各 m4a ファイルのビットレートを、それぞれ ffmpeg で64kbpsに落します:
ffmpeg -i input.m4a -ab 64k output.m4a
- 出力ファイルを元のファイル名に変更してファイルを差し替えます。
- 再度zipで圧縮し、拡張子を pptx や ppsx に戻して完了です。
- このときzipの直下に _rels や ppt, [Content_Types].xml などができるように注意
- GUIで行うならファイルエクスプローラーの「右クリック > 新規作成 > 圧縮 (zip形式)フォルダー」でzipを作成し、それを開いて必要なファイルやフォルダをドラッグ&ドロップ
音声付きスライドの圧縮スクリプト
以上の処理を自動で行うために、Windows 用にはバッチファイル、Mac 用には bash のシェルスクリプトを用意してみます。(以下単にスクリプトと呼びます。)
仕様
- スクリプトと同じフォルダに
ppt-in
フォルダがあり、ここにファイルサイズを圧縮したい pptx や ppsx ファイルが入っているとします。 - ffmpeg はパスが通っているか、スクリプトと同じフォルダに実行ファイルがあるとします。(以下のスクリプトの
PATH
を編集してパスを通してもよいです。) - スクリプトを実行すると、
ppt-out
フォルダに圧縮された pptx や ppsx が出力されるようにします。 - 作業領域として
__work__
を用意し、zip へのリネームや zip ファイルの展開、ffmpeg で変換したファイルの一時的な置き場などに利用します。
フォルダ構成と使用時の流れを以下の図にまとめます。
Windows用バッチファイル
Windows 10 を前提とします。zip の展開と圧縮には powershell を利用します。
@echo offsetlocalenabledelayedexpansionsetPATH=%PATH%;%SYSTEMROOT%\System32
rem set PATH=%PATH%;%SYSTEMROOT%\System32;"<ffmpegのbinフォルダへのパス>"rem Check ffmpegffmpeg-version
ifnot%ERRORLEVEL%==0(echoError: Cannotfindffmpegpauseexit/b 1)rem ===========================================================rem Set bitrate here. (Do not insert space around '=')setBITRATE=64krem ===========================================================setINPUT_DIR=ppt-in
setOUTPUT_DIR=ppt-out
setWORK_DIR=__work__
ifnotexist%INPUT_DIR%(echoError: Folder[%INPUT_DIR%]doesnotexistpauseexit/b 1)dir%INPUT_DIR%\*pptx%INPUT_DIR%\*ppsxifnot%ERRORLEVEL%==0(echoError: Nopptx/ppsx filesin[%INPUT_DIR%]folderpauseexit/b 1)ifnotexist%WORK_DIR%mkdir%WORK_DIR%ifnotexist%OUTPUT_DIR%mkdir%OUTPUT_DIR%for%%fin(%INPUT_DIR%\*.pptx %INPUT_DIR%\*.ppsx)do(rem Setup filenamesecho%%fsetpptfname=%%~nxfsetpptfbase=%%~nfsetzipfname=%WORK_DIR%\!pptfbase!.zip
setpptworkdir=%WORK_DIR%\!pptfbase!echo!zipfname!copy"%%f""!zipfname!"rem Create folder for pptx contentifexist"!pptworkdir!"rd/s /q "!pptworkdir!"mkdir"!pptworkdir!"rem Expand zip filepowershell-Command Expand-Archive -Path '!zipfname!'-DestinationPath '!pptworkdir!'ifnotexist"!pptworkdir!"\ppt\media (echoError: Nomediafolderinpptx/ppsx
pauseexit/b 1)rem Compress audio filesfor%%ain("!pptworkdir!"\ppt\media\*.m4a)do(setm4afname=%%~nxaffmpeg-i "%%a"-ab %BITRATE%"%WORK_DIR%\!m4afname!"move/y "%WORK_DIR%\!m4afname!""%%a")rem Archive againpowershell-Command Compress-Archive -Path '!pptworkdir!\*'-DestinationPath '%OUTPUT_DIR%\!pptfbase!.zip'move/y "%OUTPUT_DIR%\!pptfbase!.zip""%OUTPUT_DIR%\!pptfname!"rem Remove temoporary files/foldersdel"!zipfname!"rd/s /q "!pptworkdir!")
外側の for ループでは各 pptx/ppsx ファイルについて、内側の for ループではスライド内の各m4aファイルについて回し、すべての m4a ファイルのビットレートを 64kbps に変換しています。
ファイルやフォルダ名に半角スペースが入るかもしれないので、適宜ダブルクォートで囲っていますが、powershell への引数はシングルクォートで囲む必要があるようです。
Mac 用シェルスクリプト
bash を利用します。zip と unzip が入っていることを前提にしています。Mac 用と書いてありますが、Mac 実機では未テストです。
#!/bin/bash# PATH="$PATH":"<ffmpegのbinフォルダへのパス>"# Check commandsif!type ffmpeg.exe > /dev/null 2>&1;then
echo"Error: Cannot find ffmpeg"exit 1
fi
if!type zip > /dev/null 2>&1;then
echo"Error: Install [zip] before using this script"exit 1
fi
if!type unzip > /dev/null 2>&1;then
echo"Error: Install [unzip] before using this script"exit 1
fi# ===========================================================# Set bitrate here. (Do not insert space around '=')BITRATE=64k
# ===========================================================INPUT_DIR=ppt-in
OUTPUT_DIR=ppt-out
WORK_DIR=__work__
if[!-d$INPUT_DIR];then
echo"Error: Folder [$INPUT_DIR] does not exist"exit 1
fi
ls$INPUT_DIR/*.pp[ts]x
if[$?-ne 0 ];then
echo"Error: No pptx/ppsx files in [$INPUT_DIR] folder"exit 1
fi
if[!-d$WORK_DIR];then
mkdir-p$WORK_DIRfi
if[!-d$OUTPUT_DIR];then
mkdir-p$OUTPUT_DIRfi
for f in$INPUT_DIR/*.pp[ts]x;do# Setup filenamesecho"$f"pptfname="${f##*/}"pptfbase="${pptfname%.*}"zipfname=$WORK_DIR/$pptfbase.zip
pptworkdir=$WORK_DIR/$pptfbaseecho"$zipfname"echo"$pptworkdir"cp"$f""$zipfname"# Create folder for pptx contentif[-d"$pptworkdir"];then
rm-rf"$pptworkdir"fi
mkdir"$pptworkdir"# Expand zip file
unzip "$zipfname"-d"$pptworkdir"if[!-d"$pptworkdir"/ppt/media ];then
echo"Error: No media folder in pptx/ppsx"exit 1
fi# Compress audio filesfor a in"$pptworkdir"/ppt/media/*.m4a;do
m4afname="${a##*/}"
ffmpeg.exe -i"$a"-ab$BITRATE"$WORK_DIR/$m4afname"mv"$WORK_DIR/$m4afname""$a"done# Archive again(cd"$pptworkdir"&& zip -9-r"../../$OUTPUT_DIR/$pptfbase.zip"*)mv"$OUTPUT_DIR/$pptfbase.zip""$OUTPUT_DIR/$pptfname"# Remove temoporary files/foldersrm"$zipfname"rm-rf"$pptworkdir"done
こちらも Windows 用のバッチファイルとまったく同じ構造です。ファイル名やフォルダ名に半角スペースが入るかもしれないので、適宜ダブルクォートで囲っています。
以上をまとめたものを、こちらの GitHubのページに置いておきます。
約2分の音声付きスライドだと 3.33MB が 1.16MB になりました。(インストールされているエンコーダーにもよるかも。)
もう少し ffmpeg のパラメータをいろいろと検討してもよいしれません。