网上找到的代码,让gpt改了改
注意:偏移量一定要是offset - 4,不然视频格式不对
关于如何将视频和照片转换成苹果的实况照片,可以在macos下使用这个开源库。
https://github.com/RhetTbull/makelive
import os
import shutil
from concurrent.futures import ThreadPoolExecutor
import threading
# 全局变量,用于跟踪处理的文件数量
processed_files = 0
total_files = 0
lock = threading.Lock()
def ensure_directory_exists(directory):
if not os.path.exists(directory):
os.makedirs(directory)
def extract_mvimg(srcfile, photo_dir, video_dir):
global processed_files
basefile = os.path.splitext(os.path.basename(srcfile))[0]
offset = None
with open(srcfile, 'rb') as file:
data = file.read()
offset = data.find(b'ftypmp4')
if offset != -1:
# 保存offset之前的数据到图片文件夹
ensure_directory_exists(photo_dir)
with open(os.path.join(photo_dir, f"{basefile}.jpg"), 'wb') as prefixfile:
prefixfile.write(data[:offset])
# 保存视频数据到视频文件夹
ensure_directory_exists(video_dir)
with open(os.path.join(video_dir, f"{basefile}.mp4"), 'wb') as mp4file:
mp4file.write(data[offset - 4:])
else:
print(f"Can't find ftypmp4 in {srcfile}; skipping...")
with lock:
processed_files += 1
print(f"Processed {processed_files}/{total_files} files.")
def worker(srcdir, photo_dir, video_dir, files):
for filename in files:
srcfile = os.path.join(srcdir, filename)
extract_mvimg(srcfile, photo_dir, video_dir)
def copy_unmatched_files(srcdir, destdir, src_files, dest_files):
for file in src_files:
basefile = os.path.splitext(file)[0]
if basefile not in dest_files:
src_path = os.path.join(srcdir, file)
dest_path = os.path.join(destdir, file)
shutil.copy2(src_path, dest_path)
if __name__ == "__main__":
srcdir = "./photos" # 指定包含MVIMG*.jpg文件的目录
photo_dir = "./photos_trans" # 指定转换后的图片文件的保存目录
video_dir = "./videos" # 指定转换后的视频文件的保存目录
error_dir = "./error" # 指定错误文件的保存目录
# 确保输出文件夹存在
ensure_directory_exists(photo_dir)
ensure_directory_exists(video_dir)
ensure_directory_exists(error_dir)
# 获取所有符合条件的文件
files = [f for f in os.listdir(srcdir) if f.startswith("MVIMG_") and f.endswith(".jpg")]
total_files = len(files)
# 线程数量,可以根据实际情况调整
num_threads = 500
chunk_size = len(files) // num_threads
# 创建线程池
with ThreadPoolExecutor(max_workers=num_threads) as executor:
for i in range(num_threads):
start_index = i * chunk_size
# 确保最后一个线程处理剩余的所有文件
end_index = (start_index + chunk_size) if i != num_threads - 1 else len(files)
executor.submit(worker, srcdir, photo_dir, video_dir, files[start_index:end_index])
# 比较文件名并复制未匹配的文件
photo_files = {os.path.splitext(f)[0] for f in os.listdir(photo_dir) if f.endswith(".jpg")}
video_files = {os.path.splitext(f)[0] for f in os.listdir(video_dir) if f.endswith(".mp4")}
src_files = {os.path.splitext(f)[0] for f in files}
copy_unmatched_files(srcdir, error_dir, files, photo_files | video_files)
copy_unmatched_files(photo_dir, error_dir, os.listdir(photo_dir), src_files)
copy_unmatched_files(video_dir, error_dir, os.listdir(video_dir), src_files)