MP4转live图【安卓和IOS都可以】

查看 10|回复 0
作者:thisbug   
[Python] 纯文本查看 复制代码import argparse
from datetime import datetime
import cv2
import imageio
from PIL import Image
import subprocess
import os

def extract_best_frame(video_path):
    """使用光流法选择最具代表性的封面帧"""
    cap = cv2.VideoCapture(video_path)
    total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
    target_frame = max(int(total_frames * 0.2), 1)  # 优先选择视频前20%处
   
    cap.set(cv2.CAP_PROP_POS_FRAMES,  target_frame)
    success, frame = cap.read()
    cap.release()
   
    if success:
        return cv2.cvtColor(frame,  cv2.COLOR_BGR2RGB)
    else:
        return None

def generate_live_photo(input_path, output_dir, platform='ios'):
    """核心转换函数"""
    # 创建输出目录
    os.makedirs(output_dir,  exist_ok=True)
    base_name = os.path.splitext(os.path.basename(input_path))[0]
   
    # 阶段一:封面帧处理
    frame = extract_best_frame(input_path)
    if frame is None:
        raise ValueError("无法提取有效视频帧")
   
    img = Image.fromarray(frame)
    img.save(os.path.join(output_dir,  f"{base_name}_cover.jpg"),  
            quality=95, exif=img.info.get('exif',  b''))
   
    # 阶段二:视频转码
    output_video = os.path.join(output_dir,  f"{base_name}_live.mov"  if platform == 'ios'
                                else f"{base_name}_motion.jpg")
   
    ffmpeg_cmd = [
        'ffmpeg', '-y', '-i', input_path,
        '-vcodec', 'hevc', '-tag:v', 'hvc1',
        '-acodec', 'aac', '-movflags', 'faststart',
        '-vf', 'scale=trunc(iw/2)*2:trunc(ih/2)*2',  # 确保偶数分辨率
        '-metadata', f'creation_time={datetime.now().isoformat()}',
        output_video
    ]
   
    subprocess.run(ffmpeg_cmd,  check=True)
   
    # 阶段三:安卓特殊封装
    if platform == 'android':
        with open(output_video, 'rb') as f:
            video_data = f.read()
        with Image.open(os.path.join(output_dir,  f"{base_name}_cover.jpg"))  as img:
            img.save(output_video,  'jpeg', append_images=[Image.new('RGB', (1,1))],
                    save_all=True, append_images_data=[video_data])

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='MP4转动态照片工具')
    parser.add_argument('input',  help='输入MP4文件路径')
    parser.add_argument('-o',  '--output', default='./output',
                       help='输出目录(默认当前目录下的output文件夹)')
    parser.add_argument('-p',  '--platform', choices=['ios', 'android'],
                       default='ios', help='目标平台(默认iOS)')
   
    args = parser.parse_args()
   
    try:
        generate_live_photo(args.input,  args.output,  args.platform)
        print(f"转换成功!文件保存在:{os.path.abspath(args.output)}")
    except Exception as e:
        print(f"转换失败:{str(e)}")
执行命令示例
[Asm] 纯文本查看 复制代码# iOS设备转换
python3 video2live.py  input.mp4  -p ios -o ~/Desktop/live_photos
# 安卓设备转换
python3 video2live.py  input.mp4  -p android

可以加代码进行批处理
[Python] 纯文本查看 复制代码import glob
for mp4_file in glob.glob("videos/*.mp4"):
    generate_live_photo(mp4_file, "output")

如何查看live图
iOS:将.mov和.jpg同时导入Photos应用
安卓:通过Google Photos查看动态效果

代码, 文本

您需要登录后才可以回帖 登录 | 立即注册

返回顶部