Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7a1e8c4

Browse files
Day 15 - Video to Thumbnails to GIF with Moviepy
1 parent b63b66f commit 7a1e8c4

File tree

143 files changed

+1770
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

143 files changed

+1770
-0
lines changed

‎tutorial-reference/Day 15/1_thumbs.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from conf import SAMPLE_INPUTS, SAMPLE_OUTPUTS
2+
from moviepy.editor import *
3+
from PIL import Image
4+
5+
source_path = os.path.join(SAMPLE_INPUTS, 'sample.mp4')
6+
thumbnail_dir = os.path.join(SAMPLE_OUTPUTS, "thumbnails")
7+
thumbnail_per_frame_dir = os.path.join(SAMPLE_OUTPUTS, "thumbnails-per-frame")
8+
thumbnail_per_half_second_dir = os.path.join(SAMPLE_OUTPUTS, "thumbnails-per-half-second")
9+
10+
os.makedirs(thumbnail_dir, exist_ok=True)
11+
os.makedirs(thumbnail_per_frame_dir, exist_ok=True)
12+
os.makedirs(thumbnail_per_half_second_dir, exist_ok=True)
13+
14+
15+
clip = VideoFileClip(source_path)
16+
print(clip.reader.fps) # frames per second
17+
print(clip.reader.nframes)
18+
print(clip.duration) # seconds
19+
duration = clip.duration # clip.reader.duration
20+
max_duration = int(duration) + 1
21+
for i in range(0, max_duration):
22+
frame = clip.get_frame(i)
23+
# print(frame) # np.array numpy array # inference
24+
new_img_filepath = os.path.join(thumbnail_dir, f"{i}.jpg")
25+
# print(f"frame at {i} seconds saved at {new_img_filepath}")
26+
new_img = Image.fromarray(frame)
27+
new_img.save(new_img_filepath)
28+
29+
30+
31+
print(clip.reader.fps) # frames per second
32+
print(clip.reader.nframes)
33+
34+
fps = clip.reader.fps
35+
nframes = clip.reader.nframes
36+
seconds = nframes / (fps * 1.0)
37+
38+
for i, frame in enumerate(clip.iter_frames()):
39+
# print(frame) # np.array numpy array # inference
40+
if i % fps == 0:
41+
current_ms = int((i / fps) * 1000)
42+
new_img_filepath = os.path.join(thumbnail_per_frame_dir, f"{current_ms}.jpg")
43+
# print(f"frame at {i} seconds saved at {new_img_filepath}")
44+
new_img = Image.fromarray(frame)
45+
new_img.save(new_img_filepath)
46+
47+
48+
49+
for i, frame in enumerate(clip.iter_frames()):
50+
# print(frame) # np.array numpy array # inference
51+
fphs = int(fps/2.0)
52+
if i % fphs == 0:
53+
current_ms = int((i / fps) * 1000)
54+
new_img_filepath = os.path.join(thumbnail_per_half_second_dir, f"{current_ms}.jpg")
55+
# print(f"frame at {i} seconds saved at {new_img_filepath}")
56+
new_img = Image.fromarray(frame)
57+
new_img.save(new_img_filepath)
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from conf import SAMPLE_INPUTS, SAMPLE_OUTPUTS
2+
from moviepy.editor import * # ImageClip
3+
from PIL import Image
4+
5+
thumbnail_dir = os.path.join(SAMPLE_OUTPUTS, "thumbnails")
6+
thumbnail_per_frame_dir = os.path.join(SAMPLE_OUTPUTS, "thumbnails-per-frame")
7+
thumbnail_per_half_second_dir = os.path.join(SAMPLE_OUTPUTS, "thumbnails-per-half-second")
8+
output_video = os.path.join(SAMPLE_OUTPUTS, 'thumbs.mp4')
9+
10+
11+
this_dir = os.listdir(thumbnail_dir)
12+
filepaths = [os.path.join(thumbnail_dir, fname) for fname in this_dir if fname.endswith("jpg")]
13+
14+
# filepaths = []
15+
# for fname in this_dir:
16+
# if fname.endswith("jpg"):
17+
# path = os.path.join(thumbnail_dir, fname)
18+
# filepaths.append(path)
19+
20+
# print(filepaths)
21+
# clip = ImageSequenceClip(filepaths, fps=1)
22+
# clip.write_videofile(output_video)
23+
24+
25+
directory = {}
26+
27+
for root, dirs, files in os.walk(thumbnail_per_frame_dir):
28+
for fname in files:
29+
filepath = os.path.join(root, fname)
30+
try:
31+
key = float(fname.replace(".jpg", ""))
32+
except:
33+
key = None
34+
if key != None:
35+
directory[key] = filepath
36+
37+
new_paths = []
38+
for k in sorted(directory.keys()):
39+
filepath = directory[k]
40+
new_paths.append(filepath)
41+
42+
# clip = ImageSequenceClip(new_paths, fps=10)
43+
# clip.write_videofile(output_video)
44+
45+
my_clips = []
46+
for path in list(new_paths):
47+
frame = ImageClip(path)
48+
# print(frame.img) # numpy array
49+
my_clips.append(frame.img)
50+
51+
52+
clip = ImageSequenceClip(my_clips, fps=22)
53+
clip.write_videofile(output_video)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from conf import SAMPLE_INPUTS, SAMPLE_OUTPUTS
2+
from moviepy.editor import * # ImageClip
3+
from PIL import Image
4+
from moviepy.video.fx.all import crop
5+
6+
7+
source_path = os.path.join(SAMPLE_INPUTS, 'sample.mp4')
8+
9+
GIF_DIR = os.path.join(SAMPLE_OUTPUTS, "gifs")
10+
os.makedirs(GIF_DIR, exist_ok=True)
11+
12+
output_path1 = os.path.join(GIF_DIR, 'sample1.gif')
13+
output_path2 = os.path.join(GIF_DIR, 'sample2.gif')
14+
15+
clip = VideoFileClip(source_path)
16+
fps = clip.reader.fps
17+
subclip = clip.subclip(10, 20)
18+
subclip = subclip.resize(width=500)
19+
# subclip.write_gif(output_path1, fps=fps, program='ffmpeg')
20+
21+
22+
w, h = clip.size
23+
subclip2 = clip.subclip(10, 20)
24+
square_cropped_clip = crop(subclip2, width=320, height=320, x_center=w/2, y_center=h/2)
25+
26+
# square_cropped_clip.write_gif(output_path2, fps=fps, program='ffmpeg')
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from conf import SAMPLE_INPUTS, SAMPLE_OUTPUTS
2+
from moviepy.editor import *
3+
from moviepy.audio.fx.all import volumex
4+
from PIL import Image
5+
6+
source_path = os.path.join(SAMPLE_INPUTS, 'sample.mp4')
7+
source_audio_path = os.path.join(SAMPLE_INPUTS, 'audio.mp3')
8+
9+
mix_audio_dir = os.path.join(SAMPLE_OUTPUTS, "mixed-audio")
10+
os.makedirs(mix_audio_dir, exist_ok=True)
11+
og_audio_path = os.path.join(mix_audio_dir, 'og.mp3')
12+
final_audio_path = os.path.join(mix_audio_dir, 'final-audio.mp3')
13+
final_video_path = os.path.join(mix_audio_dir, 'final-video.mp4')
14+
15+
video_clip = VideoFileClip(source_path)
16+
17+
original_audio = video_clip.audio
18+
original_audio.write_audiofile(og_audio_path)
19+
20+
background_audio_clip = AudioFileClip(source_audio_path)
21+
bg_music = background_audio_clip.subclip(0, video_clip.duration)
22+
23+
24+
# bg_music = bg_music.fx(volumex, 0.10)
25+
bg_music = bg_music.volumex(0.10)
26+
# bg_music.write_audiofile()
27+
28+
final_audio = CompositeAudioClip([original_audio, bg_music])
29+
final_audio.write_audiofile(final_audio_path, fps=original_audio.fps)
30+
31+
32+
# new_audio = AudioFileClip(final_audio_path)
33+
# final_clip = video_clip.set_audio(new_audio)
34+
35+
final_clip = video_clip.set_audio(final_audio)
36+
final_clip.write_videofile(final_video_path, codec='libx264', audio_codec="aac")
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
from conf import SAMPLE_INPUTS, SAMPLE_OUTPUTS
2+
from moviepy.editor import *
3+
from moviepy.audio.fx.all import volumex
4+
from PIL import Image
5+
6+
source_path = os.path.join(SAMPLE_INPUTS, 'sample.mp4')
7+
source_audio_path = os.path.join(SAMPLE_INPUTS, 'audio.mp3')
8+
9+
mix_audio_dir = os.path.join(SAMPLE_OUTPUTS, "mixed-audio")
10+
os.makedirs(mix_audio_dir, exist_ok=True)
11+
og_audio_path = os.path.join(mix_audio_dir, 'og.mp3')
12+
final_audio_path = os.path.join(mix_audio_dir, 'overlay-audio.mp3')
13+
final_video_path = os.path.join(mix_audio_dir, 'overlay-video.mp4')
14+
15+
video_clip = VideoFileClip(source_path)
16+
17+
original_audio = video_clip.audio
18+
original_audio.write_audiofile(og_audio_path)
19+
20+
background_audio_clip = AudioFileClip(source_audio_path)
21+
#
22+
w, h = video_clip.size
23+
fps = video_clip.fps
24+
25+
intro_duration = 5
26+
intro_text = TextClip("Hello world!", fontsize=70, color='white', size=video_clip.size)
27+
intro_text = intro_text.set_duration(intro_duration)
28+
intro_text = intro_text.set_fps(fps)
29+
intro_text = intro_text.set_pos("center")
30+
31+
intro_music = background_audio_clip.subclip(0, intro_duration)
32+
33+
intro_text = intro_text.set_audio(intro_music)
34+
35+
# intro_text.write_videofile(final_video_path)
36+
watermark_size = 60
37+
watermark_text = TextClip("CFE", fontsize=watermark_size, color='white', align='West', size=(w, watermark_size))
38+
watermark_text = watermark_text.set_fps(fps)
39+
watermark_text = watermark_text.set_duration(video_clip.reader.duration)
40+
watermark_text = watermark_text.margin(left=10, right=10, bottom=2, opacity=0)
41+
watermark_text = watermark_text.set_position(("bottom"))
42+
43+
# cvc = CompositeVideoClip([watermark_text], size=video_clip.size)
44+
# cvc = cvc.set_duration(video_clip.reader.duration)
45+
# cvc = cvc.set_fps(fps)
46+
# cvc = cvc.set_audio(None)
47+
48+
overlay_clip = CompositeVideoClip([video_clip, watermark_text], size=video_clip.size)
49+
overlay_clip = overlay_clip.set_duration(video_clip.reader.duration)
50+
overlay_clip = overlay_clip.set_fps(fps)
51+
overlay_clip = overlay_clip.set_audio(None)
52+
53+
og_audio = AudioFileClip(og_audio_path)
54+
overlay_clip = overlay_clip.set_audio(og_audio)
55+
56+
57+
final_clip = concatenate_videoclips([intro_text, overlay_clip])
58+
final_clip.write_videofile(final_video_path, codec='libx264', audio_codec="aac")

‎tutorial-reference/Day 15/Pipfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[[source]]
2+
name = "pypi"
3+
url = "https://pypi.org/simple"
4+
verify_ssl = true
5+
6+
[dev-packages]
7+
8+
[packages]
9+
moviepy = "*"
10+
pillow = "*"
11+
12+
[requires]
13+
python_version = "3.8"

‎tutorial-reference/Day 15/conf.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import os
2+
3+
ABS_PATH = os.path.abspath(__file__)
4+
BASE_DIR = os.path.dirname(ABS_PATH)
5+
DATA_DIR = os.path.join(BASE_DIR, "data")
6+
SAMPLE_DIR = os.path.join(DATA_DIR, "samples")
7+
SAMPLE_INPUTS = os.path.join(SAMPLE_DIR, "inputs")
8+
SAMPLE_OUTPUTS = os.path.join(SAMPLE_DIR, 'outputs')
17.2 MB
6.8 MB
Binary file not shown.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /