Delete the Live Photo MOV file that corresponds to a non-existent Live photo.

代码

#!/bin/bash
DIR_PATH="/share/Photo/手机相册备份/"
FFPROBE_PATH="/share/CACHEDEV1_DATA/.qpkg/MediaSignPlayer/CodexPackExt/static/bin/ffprobe"
SHORT_VIDEOS_FILE="/share/CACHEDEV2_DATA/备份/照片备份/find-5s-mov.short_videos.txt"
ERROR_VIDEOS_FILE="/share/CACHEDEV2_DATA/备份/照片备份/find-5s-mov.ERROR_videos.txt"
PROCESSED_VIDEOS_FILE="/share/CACHEDEV2_DATA/备份/照片备份/processed_videos.txt"
GREEN='\033[32m'  # 设置绿色文本颜色
RED='\033[31m'    # 设置红色文本颜色
NC='\033[0m'      # 恢复默认文本颜色

# 创建 processed_videos.txt 文件如果不存在
touch "$PROCESSED_VIDEOS_FILE"

# 设置是否已跳过检测文件的标志
is_skipped=false

# 使用 while read 读取 find 命令的输出,并用双引号包裹变量,以处理含有空格的文件名和路径
find "$DIR_PATH" \( -iname "*.mov" -o -iname "*.mp4" \) ! -path "*/@Recycle/*" ! -path "*/.@__thumb/*" -print0 | while IFS= read -r -d '' mov_file; do
    if grep -Fxq "$mov_file" "$PROCESSED_VIDEOS_FILE"; then
        # 视频文件已经处理过,跳过检测并提示
        if ! $is_skipped; then
            echo "正在跳过已检测文件..."
            is_skipped=true
        fi
        continue
    fi

    if [ ! -f "${mov_file%.*}.JPG" ] && [ ! -f "${mov_file%.*}.jpg" ] && [ ! -f "${mov_file%.*}.HEIC" ] && [ ! -f "${mov_file%.*}.heic" ]; then
        output="$("$FFPROBE_PATH" -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$mov_file" 2>&1)"

        # 逐行检查输出内容,找到有效的时长信息
        duration=""
        while IFS= read -r line; do
            # 判断该行是否为数字(时长信息)
            if [[ "$line" =~ ^[0-9]+\.[0-9]+$ ]]; then
                duration="$line"
                break
            fi
        done <<< "$output"

        # 判断是否成功获取到时长信息
        if [[ -n "$duration" ]]; then
            if [ "$(echo "$duration < 5" | busybox bc)" -eq 1 ]; then
                echo -e "${GREEN}$mov_file - $duration${NC}"  # 符合条件,显示绿色
                echo "rm \"$mov_file\"" >> "$SHORT_VIDEOS_FILE"
            else
                echo "$mov_file - $duration"  # 不符合条件,显示正常颜色
            fi
        else
            echo -e "${RED}$mov_file - 错误的视频文件${NC}"  # 无法获取时长的视频,显示红色
            echo "rm \"$mov_file\"" >> "$ERROR_VIDEOS_FILE"
        fi

        # 将处理过的视频文件路径添加到 processed_videos.txt 中
        echo "$mov_file" >> "$PROCESSED_VIDEOS_FILE"
    fi
done
echo -e "\033[32m完成!\033[0m"

为什么有这个脚本

iPhone的Live Photo照片由一张照片+一个小于5秒的MOV视频组成。
通过工具或者手机App将iPhone照片上传到QNAP里,会自动分解成2个文件。
当在QNAP中,通过QuMagie AI相册删除Live Photo照片,系统仅仅删除了照片文件本身,配套的Live Photo MOV文件还保留。

ChatGPT 讲解工作原理

这个脚本的目的是搜索同名的图片是否存在Live Photo MOV文件,如果存在,则跳过检测,因为Live Photo通常包含一个MOV视频文件和一个同名的JPG或HEIC图像文件。如果只有视频文件而没有图片文件,则检测视频的时长是否小于5秒,小于5秒则表示这个视频不是必须的,可以删除。

具体来说,这段代码的执行过程如下:

  • 将目录路径"/share/Photo/手机相册备份/"和ffprobe程序路径"/share/CACHEDEV1_DATA/.qpkg/MediaSignPlayer/CodexPackExt/static/bin/ffprobe"分别赋值给变量DIR_PATH和FFPROBE_PATH。

  • 将空字符串的内容写入名为"short_videos.txt"的文件。

  • 使用"find"命令在指定目录下查找所有扩展名为.mov的文件,同时使用"! -path"参数排除掉包含字符串"@Recycle"和".@__thumb"的文件夹。然后使用一个for循环遍历所有查找到的视频文件。

  • 使用if条件语句判断视频文件是否存在与其同名的JPG或HEIC格式的图片文件。如果不存在,则执行以下步骤:
    使用ffprobe程序获取视频文件的时长。

  • 判断视频时长是否小于5秒,如果小于5秒,则将该视频文件记录到输出文件find-5s-mov.shshort_videos.txt中,并标记为绿色。
    对于无法获取时长的视频文件(例如由于文件格式错误等原因),将其记录到输出文件find-5s-mov.ERROR_videos.txt中,并标记为红色。

注意

用这个代码的前提是已经安装CAYIN MediaSign Player,并且购买了11.9USD的H.265授权。
其中文件short_videos.txt里面是搜索到的MOV文件绝对路径,为了安全起见,可以手动查看生成的文件列表是否正确,查看对应MOV文件是否有同名的JPG/HEIC照片,如果没有,证明生成的文件是正确的。
对于无法获取时长/损坏/不可识别的视频文件,会在窗口显示红色文字,并且输出到find-5s-mov.ERROR_videos.txt中,可以手动查看该文件或删除。
脚本会保存已经检测过的视频文件名,下次运行会跳过这些文件,检测新的文件。
之后在shell里运行 short_videos.txt 里面的代码即可删除对应MOV文件。