之前发过Armbian下合并小米摄像头的脚本,今天我们在群晖上安装,方法都类似。
首先登录群晖后台,套件中心-社群-添加套件来源,添加矿神源 https://spk7.imnks.com
搜索python3.11和FFmpeg7进行安装
安装完python版本还是3.8,不过不重要了,群晖控制面板打开SSH,登录后输入sudo -i切换root
执行命令
curl https://bootstrap.pypa.io/pip/3.8/get-pip.py -o /root/get-pip.py python3 /root/get-pip.py
安装
pip install loguru
保存以下代码另存为main.py,注意跟之前代码不一样,音频用的是libmp3lame。
上传到群晖任意目录
import argparse import os import subprocess from pathlib import Path from loguru import logger import platform parser = argparse.ArgumentParser(description='合并米家摄像头视频,以天为单位。') parser.add_argument('indir', help='原米家摄像头视频目录。') parser.add_argument('--outdir', default='./', help='合并后视频存放目录,目录不存在会被创建。默认当前目录。') args = parser.parse_args() skip_filenames = [] def merge_vids(vidlist_file: str, tofile: str): """执行 ffmpeg 命令合并视频。""" # 需要对音频重新编码,否则会报错: # Could not find tag for codec pcm_alaw in stream #1, codec not currently supported in container when concatenating 2 files using ffmpeg # ffmpeg -y overwrite if platform.system().lower() == "windows": cmd = f"ffmpeg -f concat -safe 0 -i {vidlist_file} -c:v copy -c:a flac -strict -2 {tofile}" subprocess.run(cmd) else: cmd = f"ffmpeg -y -f concat -safe 0 -i {vidlist_file} -c:v copy -c:a libmp3lame -strict -2 {tofile}" subprocess.run(cmd,shell=True) def has_subdirectories(directory): subdirectories = [item for item in os.listdir(directory) if os.path.isdir(os.path.join(directory, item))] return bool(subdirectories) def merge_dirs(indir: str, outdir: str, date_name: str, parent_path: str): """合并目录下的监控文件,在当前目录生成以天为单位的视频。 indir 结构: indir 2021051001 2021051002 2021051003 ... 即,子目录结构为:年月日时。 """ if not Path(outdir).exists(): logger.info(f'{outdir} 不存在,即将被创建') Path(outdir).mkdir(parents=True) date_dict = {} if Path(indir).is_file(): print("indir is file:", indir) return # 小米第一代文件目录有多层 for d in Path(indir).iterdir(): if d.is_file(): # 兼容一级目录是视频文件 date_dict[date_name] = [Path(indir)] break if not d.is_dir(): continue date = d.stem[:8] if date not in date_dict: date_dict[date] = [] date_dict[date].append(d) for ds_date, ds in date_dict.items(): videos = [] for d in ds: mp4_list = list(Path(d).glob("*.mp4")) videos.extend(mp4_list) print("data_dict:",d,has_subdirectories(Path(d))) if len(videos) == 0 and Path(d).is_dir() and has_subdirectories(Path(d)): # 往下层递归 merge_dirs(Path(d), outdir, date_name, ds_date) logger.info(f"{ds_date}, {len(videos)} videos") if not videos: continue videos = sorted(videos, key=lambda f: int(f.stem.split("_")[-1])) videos = [ "file " + str(f.resolve(strict=True)).replace("\\", "/") for f in videos ] # 直接使用 outdir 作为输出目录 vidslist_path = f"{outdir}/vidslist.txt" Path(vidslist_path).write_text("\n".join(videos), encoding="utf8") merge_vids(vidslist_path, Path(outdir).joinpath(f"{ds_date}.mp4")) def startup(indir: str, outdir: str): for date in Path(indir).iterdir(): date_name = Path(date).name if date_name in skip_filenames: continue print(f"start merge:{date_name} video") merge_dirs(Path(date), outdir, date_name, "") if __name__ == "__main__": startup(args.indir, args.outdir)
SSH里面执行命令把脚本复制到root根目录
cp /volume1/Work/main.py /root
执行命令进行测试
/volume1/Work/mi为视频原始目录
如/volume1/Work/xiaomi_camera_videos/94F111EF3111
/volume1/Work/Video为视频合并后保存目录
python3 main.py /volume1/Work/mi --outdir /volume1/Work/Video
确定无误后执行命令
nohup python3 main.py /volume1/Work/mi --outdir /volume1/Work/Video &
nohup开头和&为后台自动运行合并命令,关掉ssh也不影响。
最后可以安装openlist(alist)进行网盘同步。
本文作者为dwf135,转载请注明。