Google Colaboratory で動画再生
まず,必要なライブラリ
import cv2
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
from IPython.display import HTML
from IPython.display import IFrame
from IPython.display import display
!pip install youtube_dl
import youtube_dl
1. Youtube 動画の埋め込み再生
HTML(r'<iframe width="560" height="315" src="https://www.youtube.com/embed/GrkyTO9uu-c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>')
または
IFrame(src="https://www.youtube.com/embed/GrkyTO9uu-c",width=560,height=315)
前者は,最近の python で実行すると,IFrame() を使うようにという警告がでる.
どちらも,セルの一番最後でないと動画は表示されない.
動画を連続して表示したければ,display()で囲んでやればいい.たとえば,
print("IPython.display.HTML() による youtube 動画の表示")
display(HTML(r'<iframe width="560" height="315" src="https://www.youtube.com/embed/GrkyTO9uu-c" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>'))
print("IPython.display.IFrame() による youtube 動画の表示")
display(IFrame(src="https://www.youtube.com/embed/GrkyTO9uu-c",width=560,height=315))
次に,ローカルで持っている動画ファイルの表示方法について説明したい.
静止画のリストからIPythonで表示できるアニメーションを作って再生する関数
opencv を使えば動画を静止画に分解するのは簡単であるので,静止画のリストを引数としてとり,それを動画として再生するプログラムを作ればよい.
def makeAnimation(frames):
plt.figure(figsize=(frames[0].shape[1]/72.0, frames[0].shape[0]/72.0), dpi=72)
patch = plt.imshow(frames[0])
plt.axis('off')
def animate(i):
patch.set_data(frames[i])
anim = FuncAnimation(plt.gcf(), animate, frames=len(frames), interval=1000/30.0)
display(HTML(anim.to_jshtml()))
実行例
想定として,処理対象動画を Youtube動画から切り出し,それを notebook 内で表示するというシチュエーションを考えよう.
実験用動画をYoutube動画からとってきて,30フレーム取り出してローカルに保存し,それを notebook 内で再生するプログラムを作ってみる.
Youtube 動画を一時的に保存
# 動画を一時的に tmpv.mp4 という名前で作業フォルダに保存
# Youtube動画には著作権がある.くれぐれも悪用しないように
url = 'https://youtu.be/GrkyTO9uu-c'
vname = 'tmpv.mp4'
ydl = youtube_dl.YoutubeDL({'outtmpl': vname,'format':'18'}) # 640x360 mp4
# ydl = youtube_dl.YoutubeDL({'outtmpl': 'test.%(ext)s','format':'133'}) # 426x230 mp4
# ydl = youtube_dl.YoutubeDL({'outtmpl': 'test.%(ext)s','format':'135'}) # 854x480 mp4
# ydl = youtube_dl.YoutubeDL({'outtmpl': 'test.%(ext)s','format':'136'}) # 1280x720 mp4
# ydl = youtube_dl.YoutubeDL({'outtmpl': 'test.%(ext)s','format':'137'}) # 1920x1080 mp4
# meta = ydl.extract_info(url, download=False)
# print(meta['format'])with ydl:
result = ydl.extract_info(url,download=True)
上のプログラムは Youtube にアップしてある動画を 640x360 の解像度でダウンロードし,"tmpv.mp4" という名前で保存する.
上のプログラムで保存した,tmpv.mp4 の最初の30フレームを表示するプログラム.
movie = "tmpv.mp4"
cap = cv2.VideoCapture(movie)
# 最初の30フレームを取り出す
ret, frame = cap.read()
imgs = [frame] # 最初のフレーム
for i in range(29):
ret, frame = cap.read()
imgs.append(frame)
makeAnimation(frames=imgs)
動画だけ表示してほしいのだが,動画のあとに最初のフレームが静止画として表示されてしまう.