Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 979fe53

Browse files
committed
WIP: handle subdirectories.
Currently works, but a sequence that goes across directory boundaries won't be assembled correctly by `ffmpeg`.
1 parent 231ed1c commit 979fe53

3 files changed

Lines changed: 57 additions & 11 deletions

File tree

constants.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,17 @@
1818
# named DSC05234.JPG
1919
photo_prefix = 'DSC'
2020

21-
# Location of photos, e.g. where you copied the contents of your SD card.
21+
# Location of photos, e.g. where you copied the contents of your SD card. If
22+
# your camera created multiple folders (e.g. the file counter has looped back to
23+
# zero), point this to the folder containing the subfolders.
2224
import os
23-
input_dir = os.path.join(os.path.expanduser('~'), 'Desktop', 'DCIM', '100MSDCF')
25+
input_dir = os.path.join(os.path.expanduser('~'), 'Desktop', 'DCIM')
26+
27+
# A regex pattern to search for a number in photo subdirectories; e.g. if
28+
# `input_dir` contains subfolders '100MSDCF' and '101MSDCF', you want something
29+
# that will extract the '100' and '101'. The first matching group is taken as
30+
# the number.
31+
subdir_number_pattern = '([0-9]+)'
2432

2533
# Location of the final boomerang videos
2634
output_dir = os.path.join(input_dir, 'boomerangs')

sorter.py

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,41 @@
22

33
import os, shutil
44
from constants import *
5+
import re
56

67
set_offset = 0 # number for first set in this run.
78

89
files = os.listdir(input_dir)
9-
if len(files) == 0:
10-
print('No files.')
11-
exit(0)
1210

13-
last_date = None
14-
sets = []
11+
# Check for directories or files.
12+
has_files = False
13+
has_directories = False
1514
for file in sorted(files):
1615
filename = os.path.join(input_dir, file)
1716
if os.path.isdir(filename):
18-
continue
17+
has_directories = True
18+
elif os.path.isfile(filename):
19+
has_files = True
20+
21+
if not has_files and not has_directories:
22+
raise RuntimeError('No files or directories to sort through.')
23+
if has_files and has_directories:
24+
raise RuntimeError('Found both files and directories. Cannot proceed.')
25+
26+
if has_directories:
27+
# Collect filenames from the subdirectories. We only go one deep.
28+
actual_files = []
29+
for d in sorted(files):
30+
dirname = os.path.join(input_dir, d)
31+
sub_files = os.listdir(dirname)
32+
for file in sorted(sub_files):
33+
actual_files.append(os.path.join(dirname, file))
34+
else:
35+
actual_files = [os.path.join(input_dir, file) for file in sorted(files)]
36+
37+
last_date = None
38+
sets = []
39+
for filename in actual_files:
1940
if not photo_ext in filename:
2041
continue
2142
# mtime is the only one that works, sadly the resolution is not high enough
@@ -60,8 +81,24 @@
6081
new_dir = os.path.join(input_dir, 'set_%02d' % set_num)
6182
os.makedirs(new_dir, exist_ok=False)
6283
for old_file in set:
63-
# By putting a hyphen in the name, we can then use negative file numbers
64-
# to encode sequences in reverse.
65-
newFile = os.path.join(new_dir, f'image-{os.path.basename(old_file)[len(photo_prefix):]}')
84+
# If we had subdirs, take digits from there to maintain image order
85+
# across folder boundaries.
86+
image_num_and_ext = os.path.basename(old_file)[len(photo_prefix):]
87+
if has_directories:
88+
subdir = os.path.basename(os.path.dirname(old_file))
89+
dir_num_match = re.search(subdir_number_pattern, subdir)
90+
if dir_num_match is None:
91+
raise RuntimeError(f'Photo subdirectory "{subdir}" has no numbers.')
92+
dir_num = dir_num_match[0]
93+
# By putting a hyphen in the name, we can then use negative file numbers
94+
# to encode sequences in reverse.
95+
# TODO: This doesn't work; it causes a large jump in the number and
96+
# ffmpeg won't follow the sequence. We need to remember the last
97+
# number and then add it to each subsequent dir, or do something
98+
# more clever.
99+
new_file = f'image-{dir_num}{image_num_and_ext}'
100+
else:
101+
new_file = f'image-{image_num_and_ext}'
102+
newFile = os.path.join(new_dir, new_file)
66103
print(f'\t{old_file} --> {newFile}')
67104
shutil.move(old_file, newFile)

video_maker.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def get_output(cmd: str) -> str:
5353
start_num = int(os.path.basename(files[1])[len('image-'):-len(photo_ext)])
5454
num_pattern = f'%0{len(str(start_num))}d'
5555
vid_file_fwd = os.path.join(input_dir, f'{set_name}_forward.mp4')
56+
# TODO: Should probably have a config parameter for '.JPG'
5657
ffmpeg = f"{ffmpeg_call} -y -start_number {start_num} -r {fps} -i \"{set}/image-{num_pattern}.JPG\" " \
5758
f"-vf \"{vf}\" -vcodec libx264 -crf {quality} -pix_fmt yuv420p \"{vid_file_fwd}\" " \
5859
f"> {dev_null} 2>&1"

0 commit comments

Comments
 (0)