動画のスライドを抽出する
動画の全スライドを抽出して PDF 化する
スライドの抽出処理
ffmpeg で画像切り出しをした所で下記の記事を発見した。
ありがたや〜早速動かしてみる。
必要なパッケージのインストール
brew install ffmpeg imagemagick
touch movie2slide.sh
movie2slide.sh
#!/bin/bash for command in ffmpeg convert diff do which command$ if [ $? != 0 ]; then echo "$command not found." exit 1 fi done PSNR_threadshold=30 SLIDE_PREFIX=slide RATE=1 isRATEdecimal=$( echo "$RATE > 1" | bc ) PHOTOFORMAT=jpg moviefile=$1 pathname_tmp=${moviefile// /_} pathname=${pathname_tmp%.*} workdirname="${pathname}.$( date +"slide_%Y%m%d_%H%M%S" )" mkdir $workdirname ffmpeg -i "$1" -map 0:1 -vn -ac 2 -acodec pcm_s16le -f wav ${workdirname}/audio.wav ffmpeg -i "$1" -map 0:1 -vn -ac 2 -acodec libmp3lame -f wav ${workdirname}/audio.mp3 ffmpeg -i "$1" -r ${RATE} ${workdirname}/${SLIDE_PREFIX}.%d.png cd ${workdirname} finalslide_number=$( ls | wc -l ) merge_and_delete_duplicated_photos() { local same_picture_begin=$1 local same_picture_end=$2 local j if [ "${same_picture_begin}" != "${same_picture_end}" ];then if [ "${SEQUENCE}" != "" ]; then convert -evaluate-sequence ${SEQUENCE} $( for j in $( seq ${same_picture_begin} ${same_picture_end} ) ; do echo ${SLIDE_PREFIX}.$j.png done ) zmedian.${PHOTOFORMAT} fi for j in $( seq $((same_picture_begin+1)) ${same_picture_end} ) ; do rm ${SLIDE_PREFIX}.$j.png done if [ -e zmedian.${PHOTOFORMAT} ]; then mv zmedian.${PHOTOFORMAT} ${SLIDE_PREFIX}.${same_picture_begin}.${PHOTOFORMAT} fi fi if [ "${PHOTOFORMAT}" != "png" ]; then convert ${SLIDE_PREFIX}.${same_picture_begin}.png ${SLIDE_PREFIX}.${same_picture_begin}.${PHOTOFORMAT} rm ${SLIDE_PREFIX}.${same_picture_begin}.png else pngquant ${SLIDE_PREFIX}.${same_picture_begin}.png mv ${SLIDE_PREFIX}.${same_picture_begin}-fs8.png ${SLIDE_PREFIX}.${same_picture_begin}.png fi } detect_duplicated_photos() { local same_picture_begin=1 local same_picture_end=1 local i for i in $( seq 1 ${finalslide_number} ); do filename_current=${SLIDE_PREFIX}.$i.png filename_next=${SLIDE_PREFIX}.$((i+1)).png filename_start=${SLIDE_PREFIX}.${same_picture_begin}.png if [ -e $filename_current ] && [ -e $filename_next ]; then diff -b $filename_start $filename_next > /dev/null if [ $? -eq 0 ]; then PSNR=0 else PSNR=$( compare -metric PSNR $filename_start $filename_next zdiff.png 2>&1 ) rm zdiff.png PSNR=${PSNR%.*} fi echo -en "$filename_start -> $filename_next : PSNR = " $PSNR if [ $PSNR -eq 0 ] || [ $PSNR -ge $PSNR_threadshold ]; then echo -n " : delete" same_picture_end=$((i+1)) else echo -n " : convert to ${PHOTOFORMAT}" merge_and_delete_duplicated_photos $same_picture_begin $same_picture_end same_picture_begin=$((i+1)) same_picture_end=$((i+1)) fi echo "" fi done merge_and_delete_duplicated_photos $same_picture_begin $same_picture_end } rename_filename_with_timestamped() { for file in $( ls ${SLIDE_PREFIX}.*.${PHOTOFORMAT} ) do filename_tmp=${file%%.${PHOTOFORMAT}} number=${filename_tmp##${SLIDE_PREFIX}.} number=$(( number + 0 )) raw_seconds=$( echo "scale=2; $number/$RATE" | bc ) hour=$( echo "scale=0; $raw_seconds/3600" | bc ) minute=$( echo "scale=0;($raw_seconds -$hour*3600)/60" | bc ) second=$( echo "scale=0;($raw_seconds -$hour*3600 -$minute*60)*2/2" | bc ) if [ $isRATEdecimal == 1 ]; then millisecond=$( echo "scale=0; ($raw_seconds -$hour*3600 -$minute*60 -$second)*100" | bc ) timestamp=$(printf "%02d.%02d.%02d.%02d" ${hour%.*} ${minute%.*} ${second%.*} ${millisecond%.*} ) else timestamp=$(printf "%02d.%02d.%02d" $hour $minute $second ) fi mv $file ${SLIDE_PREFIX}.$timestamp.${PHOTOFORMAT} done for file in $( ls ${SLIDE_PREFIX}.*.${PHOTOFORMAT} ) ; do touch $file ; done } detect_duplicated_photos rename_filename_with_timestamped
実行
zsh ./movie2slide.sh {xxxxx}.mp4
僕の環境で 1 時間の動画を変換するのに 20 分ほどかかった。 また、途中ディレクトリの容量を観察してみると 10GB を超えていたので容量には注意。 最初に出来上がった PNG ファイル 4200 枚が 重複分を削除し、614 枚まで減った。 最終的に 43.8MB に落ち着いた。
PDF 化処理
こちらの記事に大枠はありました。
ありがたや〜。
必要なパッケージのインストール
pip3 install img2pdf
pip3 install natsort
touch convert2pdf.py
img2pdf が brew パッケージにあれば 1 つのシェルスクリプトファイルだけで完結するのだが、仕方なし。 記事では出力された画像がソートされていないのでパッケージを追加して PDF を作成。
convert2pdf.py
import os import img2pdf from PIL import Image if __name__ == '__main__': pdf_FileName = "./output.pdf" # Export PDF filename png_Folder = "./jpg/" # Input Images Directory extension = ".jpg" # convert only jpg files with open(pdf_FileName,"wb") as f: f.write(img2pdf.convert([Image.open(jpg_Folder+j).filename for j in natsorted(os.listdir(jpg_Folder))if j.endswith(extension)]))
よく使うが覚えていないコマンド群
なぜ書くか?
誰しも何度もググる事はある。むしろググればわかる、という安心感は依存さえ覚える。
ただ、本当に何回も同じ検索をするのは非効率なので(覚えろという話はさておき)、
よく使うが覚えきれていないコマンドを列挙する。
もし閲覧された方が面白いと思われるものがあれば嬉しい。
コマンド一覧(逐次追加)
連番ファイルの作成
touch hoge-{1..30}.md
ファイルサイズ順に降順にソート
ls -lS
特定の文字列の検索
find . -type f -print | xargs grep 'hoge'
一つ上の階層に移動
..
いつもcd ..としがちなので。
npm run devで開くlocalhostのポート番号を変更
ポート番号の変更
Reactではデフォルトのポート番号として3000番が割り当てられている。
ただこれだと、複数のローカルサーバを立ち上げるときにポート番号がバッティングしてしまう。
それを避けるためにpackage.jsonにおいて下記の変更を行なう。
(Nextjsを使っているがreact-scriptsでも同様)
"scripts": { "dev": "PORT=3001 next dev", "build": "next build", "start": "PORT=3001 next start" },
[GitHub]Deprecation Notice
Github から届いたメール
Hi @hoge,
You recently used a password to access the repository at hoge/fuga with git using git/2.30.1 (Apple Git-130).
Basic authentication using a password to Git is deprecated and will soon no longer work. Visit https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/ for more information around suggested workarounds and removal dates.
Thanks, The GitHub Team
ふむふむ、2021 年 8 月 13 日以降はパスワードを用いたアクセスができなくなるらしい。 そのため、今のうちに 2 段階認証やトークンを用いたアクセスに切り替えればよいとのこと。
上記記事はためになったものの、情報が不足していたので実際に僕が行なった設定を書いておく。
設定手順
2 段階認証を有効化する
下記の Github のセキュリティページより有効化。 簡単なので説明は不要でしょう。MFA か SMS 認証かを選べます。
Personal access tokens を発行する
下記の Github のアクセストークンページより新規トークンを作成。
repo から gist までを全てチェックの上 Generate token。
表示されるトークンは一度きりなので必ずどこかに保存。
接続確認
Terminal から下記コマンドを実行し、クレデンシャル情報をリセットする。
git credential-osxkeychain erase host=github.com protocol=https
次に先ほど保存したトークンを用いて適当な自身のプライベートリポジトリをクローン。
git clone https://github.com/hoge/fuga.git Cloning into 'fuga'... Username for 'https://github.com': your-username Password for 'https://hoge@github.com': your-token
MacでSafariとChromeの間でタブをショートカットでスイッチする方法
スイッチするメリット
今開いているタブを Safari で開きたいのにな。
また逆も然りで、Chrome で開きたいのにな。
そう思う瞬間が誰にでも一度はあるはずです(ほぼない)
そう、誰が求めているかわからないニッチな話です。
僕自身はこんな使い方をしています。
という事で基本的に記事を読む時は Safari、動画を見る時は Chrome と使い分けています。
で、早速方法を調べてみてもなかなかヒットしない。
Safari から Chrome を開く方法はかろうじてヒットするものの、
逆は英語で検索してもなかなか出てこない。
1 時間程かけてなんとか見つかったので覚書。
結論
Safari から Chrome の開き方
Safari の Develop メニューを有効化
利用中の Chrome のバージョンをコピー
System Preferences > Keyboard > App Shortcuts より Safari のショートカットを追加
上記の三本立て。
まず Safari を開いて Cmd+,もしくは Menu Bar > Safari > Preferences。
一番右にある Advanced から Show Develop menu in menu bar をチェック。
そうすると Menu Bar に Develop が表示されます。
念の為確認しましょう。
Develop > Open Page With > Google Chrome.app ("Google Chrome Version")
このメニューにショートカットを割り当てます。
次に現在の Chrome のバージョンを確認します。
Chrome を開いて Cmd+,もしくは Menu Bar > Safari > Preferences。
サイドバーから About Chrome を開くとバージョンが確認できるのでこれをコピー。
私の場合 92.0.4515.107 でした。
最後にショートカットを設定します。
System Preferences を開いて、Keyboard の一番下にある App Shortcuts を開いてください。
+ボタンを押して Applications を Safari、Menu Title を Google Chrome.app ("Google Chrome Version")とします。
app と(の間に半角スペース、また()は半角である事にご注意ください。
"<Google Chrome Version"を先ほどコピーしてもらったバージョンに差し替えてくださいね。
お好きなショートカットを設定して Add。(僕は Cmd+Shift+O にしました)
完了したら是非ショートカットから実行してみてください。
Chrome から Safari の開き方
System Preferences > Keyboard > App Shortcuts より Safari のショートカットを追加
上記の二本立て。
先ほどは標準のメニューにショートカットを追加しただけでしたが、
こちらは用意されていないため自分で作らねばなりません。
そこで Automator.app を利用します。
New Document > Quick Actions > Utilities > Run Apple Script と進みますと
コードの編集画面が表示されます。
有志の方が処理を Gist にあげてくださっていますので、ありがたく使わせていただきましょう。
こちらのコードを貼り付けてお好きな名前で保存。
ちなみに、デフォルトで./Library/Services にファイルは保存されます。
System Preferences を開いて、Keyboard の真ん中ほどにある Services を開いてください。
一番下に先ほど保存した名前の項目が増えていますので、Add Shortcut をクリック。
お好きなショートカットを設定して Add。(僕はこちらも Cmd+Shift+O にしました)
完了したら是非ショートカットから実行してみてください。
iOS端末の標準アプリ削除・非表示方法
結論
- 「×」で簡単に消せるもの
アプリを長押しで表示される「×」を押す
これで、Podcast、Maps、iTunes Store、メールなど多くの標準アプリが消せる
- Screen Timeで機能をなくせるもの①
「Screen Time」→「Contents & Privacy Restrictions」→「Allowed Apps」
これで、Safari、Camera、Wallet、Healthが消せる
- Screen Timeで機能をなくせるもの②
「Screen Time」→「Contents & Privacy Restrictions」→「iTunes & App Store Purchases」→「Installing Apps」→「Don't Allow」
これで、App Storeが消せる
- どうにも消せないもの
下記の標準アプリを消す方法は現状見つかっていない
Clock、Settings、Photos、Phone、Message、Find My
Vimeoの動画を拡張機能等使わず直接ダウンロードする方法
拡張機能がはらむセキュリティ問題
Google Chrome を含む昨今のほとんどのブラウザには便利な拡張機能が用意されている。 動画の再生速度を変更したり、煩わしい広告をブロックしたり、Amazon の価格推移を確認したり。 その便利さには抗えず、それがどんなコードで書かれているか気にせず拡張機能をインストールしてしまう。 幸いにも悪意のない拡張機能がほとんどではあるが、悪意のあるコードが仕組まれている事が実際にある。
例えば、2020 年 12 月にアンチウイルスソフトウェアの会社として長い歴史を持つ Avast が動画ダウンロードに関連する拡張機能の利用に注意を喚起している。
Google Chrome の拡張機能は基本的に JavaScript をベースとして作成されるが、したがって機能以外のコードを拡張機能のプログラム内に埋め込むことで開発者が好き勝手できるという訳だ。それにほとんどのブラウザの利用者はエンジニアではなく、もし仮にエンジニアだとしても中身のコードまで確認するような人は皆無である。よって、利用者がかなり増えた段階で調査が行われ、明るみに出たという話である。
どんなコードかもし気になる方がいらっしゃれば、発見の先駆けになったであろうチェコ語のブログ記事のリンクを記載するので、確認されたい。数多くのコードの中のよく解読しないと何をしているのかわからないたった 14 行のコードが埋め込まれていたようである。
いずれにせよ、拡張機能を利用する際は自己責任のもと可能な限り信頼のおけるものを選んでいただきたい。
Vimeo 動画のダウンロード方法
さて、早速本題にいこう。 なぜ前置きを長々とお伝えしたかというと、不必要なリスクは負わない方が良いためである。 少なくとも Vimeo の場合は公開者の設定次第ではあるが、全くセキュリティに問題のないダウンロード方法が存在する。
※ダウンロードした著作権を所有していない動画を再アップロードするなど意図的・意図的でない著作権違反にご注意を。
まずはダウンロードしたい動画のページを開く。 この時点で URL は下記の 2 種類のいずれかである。
- https://vimeo.com/{hogefuga}
- https://player.vimeo.com/video/{hogefuga}
二つ目の動画 URL であればそのまま、一つ目の動画 URL であれば{hogefuga}部分をコピーして二つ目の動画 URL 形式で開き直す。 その URL に「/config」を付け足す。つまり
https://player.vimeo.com/video/{hogefuga}/config
とし、ページを開くと白地に黒文字のみのシンプルなページが開く。 これはいわゆる JSON 形式のもので JavaScript で取り扱いのしやすいデータ形式である。 このページ内で「.mp4"」と検索すると解像度ごと(周辺に 720p、360p などが記載)に動画の URL が記載されている。 例えば、下記のような URL が見受けられる。
https://vod-progressive.akamaized.net/exp={hoge}.mp4~hmac={fuga}/vimeo-prod-skyfire-std-us/{piyo}.mp4
上記の URL を再び開くとシンプルな動画の再生画面が表示される。この画面において右下の「︙」をクリックし、「Download」をクリックすることで動画をダウンロードする事ができる。