LoginSignup
66
22

More than 1 year has passed since last update.

動画からスライドを自動生成するアプリを作りました

Last updated at Posted at 2021-12-01

この記事は クソアプリアドベントカレンダー2 の2日目の記事です。今まで傍から見ているだけでしたがついに初参加できて嬉しいです。

課題: 動画よりもスライドでサクサク見たい

WWDCセッションの内容をチェックしては発信する、ということを毎年やっている 1 のですが、なぜか昨年(2020)あたりからセッションのスライドPDFが公開されなくなりました。

セッションの動画は例年通り公開されているのですが、

動画よりもスライドのほうがシーク効率が圧倒的に良いので、やっぱりスライドが欲しい。2

で、つくったのが、

動画からスライドを抽出するiOS/macOSアプリ「Slidify」

↑この動画をSlidifyに食わせて全自動で生成したスライドが、

↑こちら。

いかがでしょう?

荒削りな部分(後述)はあるものの、私は自分用ツールとしては十分実用に耐えうると思いました。

しくみ

スライド抽出のしくみはざっくり以下のとおりです:

  • 動画のフレームを一定間隔ごとに解析
  • 以下の条件を満たすフレームだけを抽出
    • 文字がある
    • 文字領域が前フレームから一定以上変化している

これだけ。

上のロジックに該当する実装を抜粋すると、こんな感じです:

  • 一定間隔ごとの動画解析
let processingOption = VNVideoProcessor.RequestProcessingOptions()
processingOption.cadence = VNVideoProcessor.TimeIntervalCadence(processingTimeInterval)

let videoProcessor = VNVideoProcessor(url: url)
// request は VNDetectTextRectanglesRequest
try! videoProcessor.addRequest(request, processingOptions: processingOption)

let timeRange = CMTimeRange(start: CMTime.zero, end: CMTime.indefinite)
try! videoProcessor.analyze(timeRange)

VNVideoProcessor についてはこちらの記事をご参照ください:

  • 文字があるか?
// observations は VNTextObservation の配列
guard observations.count > 0 else { return false }
  • 文字領域が前フレームから一定以上変化しているか?
let intersection = bbox1.intersection(bbox2)
if intersection.area / bbox1.area < threshold {
    return true
}

文字認識も、抽出したフレーム画像同士の類似度判定も行っていません

こういう簡素な抽出ロジックのため、

  • メガネに映り込んだアイコン画像の中の文字を拾ってしまっていたり
  • 同じようなページが連続してしまっていたり

といった問題も散見されますが、
「スライドをざーっと見て概要を把握したい」という自分の用途としては重大な問題ではありませんでした。

実装はほぼ使いまわし

ほとんどの実装は、過去の個人開発アプリからの流用です。

個人開発でも使い回しやすいパーツはSwift Package化しておいて、別プロジェクトにサクッと横展開できるようにしてあります。

  • 動画選択UI
    • Chopper で実装したSwift Packageを流用
    • PHPickerViewControllerUIDocumentPickerViewControllerを利用
    • メソッド一つ呼べばアクションシートが出て、後はファイル選択時(あるいは失敗時に)completion handlerに指定した処理が実行される。
  • 文字領域検出
    • Somato で実装したSwift Packageを流用(TOTOCでも同パッケージを使っている)
    • 文字領域検出だけでなく、Visionラッパーとして自分が使いやすいようにモジュール化してある
visionHanlder.perform(video: videoURL, requestTypes: [.text], processingTimeInterval: minimumTimeInterval, resultHandler: { observations in
    // フレームごとの結果
    ...
}) { result in
    // 動画全体の処理が完了
    ...
}
  • 動画からのフレーム抽出
    • Somato, TOTOCからの流用

今回新たに実装した部分は上述の文字領域の差分判定のところぐらい。

今後の展望

以下対応しておくともっと便利に使えそう:

  • 類似画像の除去
  • コマンドラインツール化
  • コンテキストメニュー対応
    • 動画ファイル選択 → 右クリックで実行できるようにしたい

おわりに

作り終えて記事を書き始めてから思いましたが、クソアプリカレンダーには真面目すぎる題材だったかもしれません...

「作りたい!という衝動にまかせて、有用性や需要のことは考えずとにかく手を動かす」

というものづくりの姿勢から生まれたものをクソアプリと呼ぶ、と拡大解釈して投稿させていただきました。もし場違いでしたらすみません🙇🏻‍♂️こういうネタ要素の少ないものでもよろしければぜひまた参加させてください。


  1. OSSを作ったり、を書いたり、noteマガジンを書いたり。 

  2. しっかり調査する際には結局動画を見るのだとしても、どの動画を見るかどうか決めるにあたって、まずはスライドをパラパラと見てざっと概要を把握したい。 

66
22
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
66
22