まだ消化不良でしょ?
2017-12-15 追記: 以下参照:
ダウンロードという行為そのものが youtube の利用規約に反することを知りませんでした。(なお、ダウンロードするだけで著作権法違反となる、という話ではない。)以下一応読めるようにはしておくけれど、出来れば読まないで。
だって音声無視してるしね。
同じものだとつまらんので今度は以下2つの合成:
ロンドンに不思議な球体がぁ、てなもんになるかな?
スクリプトの構造は大幅に変わる:
1 #
2 import sys
3 import argparse
4 import logging
5 import json
6
7 import numpy as np
8 import av
9 from PIL import Image
10
11 if __name__ == '__main__':
12 logging.basicConfig(stream=sys.stderr, level=logging.INFO)
13 parser = argparse.ArgumentParser()
14 parser.add_argument("background")
15 parser.add_argument("greenback")
16 parser.add_argument("outfile")
17 parser.add_argument("--pick", type=str, default="[0, 0]")
18 parser.add_argument("--atol", type=int, default=30)
19 args = parser.parse_args()
20 pick = tuple(json.loads(args.pick))
21
22 icontbg = av.open(args.background)
23 icontgb = av.open(args.greenback)
24 ivstrbg = next(s for s in icontbg.streams if s.type == b'video')
25 ivstrgb = next(s for s in icontgb.streams if s.type == b'video')
26 iastrbg = next(s for s in icontbg.streams if s.type == b'audio')
27 ocont = av.open(args.outfile, "w")
28 ovstr = ocont.add_stream(codec_name="h264", rate=ivstrbg.rate)
29 oastr = ocont.add_stream(codec_name="aac", rate=iastrbg.rate)
30 ovstr.width = ivstrbg.width
31 ovstr.height = ivstrbg.height
32
33 packetsbg = icontbg.demux()
34 packetsgb = icontgb.demux(ivstrgb)
35 while True:
36 try:
37 packetbg = next(packetsbg)
38 if packetbg.stream.type == 'video':
39 iframebgs = packetbg.decode()
40 iframegbs = next(packetsgb).decode()
41 for iframes in zip(iframebgs, iframegbs):
42 logging.info(iframes)
43 imgbg = iframes[0].to_image()
44 imggb = iframes[1].to_image().resize(imgbg.size)
45 keyclr = imggb.getpixel(pick)
46
47 r = np.array(imggb.getdata(0))
48 g = np.array(imggb.getdata(1))
49 b = np.array(imggb.getdata(2))
50 a = np.zeros(r.shape)
51 a[np.logical_and(
52 np.isclose(r, keyclr[0], atol=args.atol),
53 np.isclose(g, keyclr[1], atol=args.atol),
54 np.isclose(b, keyclr[2], atol=args.atol))] = 255
55 alpha = Image.new("L", imggb.size)
56 alpha.putdata(a.flatten())
57 mask = imggb.copy()
58 mask.putalpha(alpha)
59
60 dimg = Image.composite(imgbg, imggb, mask)
61
62 ofr = av.VideoFrame.from_image(dimg)
63 for p in ovstr.encode(ofr):
64 ocont.mux(p)
65 else:
66 for iframe in packetbg.decode():
67 logging.info(iframe)
68 iframe.pts = None
69 for p in oastr.encode(iframe):
70 ocont.mux(p)
71 except StopIteration:
72 break
73
74 ocont.close()
音声と映像のレートは当然違うので (1)(2) でシンプルに zip してたようにはいかない、というわけだけれど、本当は映像のフレームレートが違ってたらダメなんだけどね、そこは同じだとして。(フレームレート違いを扱うのは多分かなり難儀。)
結果:
なんつーかあんましオモロイ例にならなくてすまん。Creative Commons なものだけでやろうとすれば限られてくるもんでなぁ。ほんとは「渋谷に不思議な球体がぁ」なんてのだったらオモロいと思ったんだけどね。