1. 项目目标

在 Ubuntu 24.04 服务器上实现自动化流程:

  1. 扫描:递归扫描 OneDrive 指定目录及其子目录下的 .ts 视频文件。
  2. 下载:将文件下载到服务器临时目录。
  3. 转码:使用 FFmpeg 将 .ts 转换为 .mp4(不改变画质,仅封装或转码音频)。
  4. 回传:将生成的 .mp4 上传回 OneDrive 原本所在的子目录。
  5. 清理:上传成功后,删除 OneDrive 上的原 .ts 文件,并清理服务器本地临时文件。

2. 准备工作

  • 一台连接互联网的 Ubuntu 24.04 服务器(已通过 SSH 连接)。
  • 一台本地电脑(Windows/Mac),用于获取 OneDrive 授权 Token。
  • 一个有效的 OneDrive 账号(确保未冻结、空间充足)。

3. 环境安装

在服务器终端执行以下命令,更新系统并安装核心工具:

1
2
3
4
5
6
7
8
# 更新软件源
sudo apt update

# 安装 FFmpeg (用于视频转码)
sudo apt install ffmpeg -y

# 安装 Rclone (用于连接 OneDrive)
sudo -v ; curl https://rclone.org/install.sh | sudo bash

4. 配置 OneDrive 连接 (Rclone)

这是最关键的一步。由于服务器没有浏览器,需要配合本地电脑完成授权。

  1. 在服务器上启动配置向导

    1
    rclone config
  2. 按照以下交互进行选择

    • n (New remote) -> 回车。
    • name: 输入 onedrive -> 回车。
    • Storage: 输入 Microsoft OneDrive 对应的数字(通常在列表里找,输入数字后回车)。
    • client_id: 直接回车(跳过)。
    • client_secret: 直接回车(跳过)。
    • Edit advanced config?: 输入 n (No)。
    • Use web browser to automatically authenticate?: 输入 n (No) (非常重要!)。
  3. 在本地电脑获取授权 Token

    • 服务器此时会显示一条命令:rclone authorize "onedrive"
    • 在你本地电脑下载 Rclone (官网下载),解压后在命令行运行上述命令。
    • 浏览器弹出登录 OneDrive 并授权。
    • 复制本地命令行中生成的长串 Token(以 {"access_token":... 开头)。
  4. 回到服务器填入 Token

    • config_token> 提示符后粘贴刚才复制的代码 -> 回车。
    • Type of connection: 输入 1 (OneDrive Personal or Business)。
    • Chose drive to use: 输入 0 (或者你想要挂载的那个盘的序号)。
    • Is that okay?: 输入 y
    • Quit: 输入 q 退出。

5. 部署自动化脚本

5.1 创建脚本文件

1
nano convert_ts.sh

5.2 写入脚本内容

将以下代码粘贴进去。**请务必根据注释修改 REMOTE_PATH 为你的实际路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/bin/bash

# ================= 配置区域 =================

# 1. Rclone 配置名称 (刚才设置的 name)
REMOTE_NAME="onedrive"

# 2. OneDrive 根扫描路径
# 脚本会扫描这个路径以及它下面的所有子文件夹
# 请修改为你实际存放 ts 文件的文件夹,例如 "/Movies"
REMOTE_PATH="/Videos/Download"

# 3. 服务器本地临时目录
LOCAL_WORK_DIR="/tmp/video_convert_workdir"

# ===========================================

# 创建本地工作目录
mkdir -p "$LOCAL_WORK_DIR"

echo "========================================================="
echo "正在递归扫描 [$REMOTE_PATH] 下的所有 .ts 文件..."

# 递归获取文件列表
FILE_LIST=$(rclone lsf "$REMOTE_NAME:$REMOTE_PATH" -R --files-only --include "*.ts")

if [ -z "$FILE_LIST" ]; then
echo "未发现 .ts 文件。"
rm -rf "$LOCAL_WORK_DIR"
exit 0
fi

# 解决文件名空格问题
IFS=$'\n'

for REL_PATH in $FILE_LIST; do
echo "------------------------------------------------------"
echo "发现文件: $REL_PATH"

DIR_NAME=$(dirname "$REL_PATH")
FILE_NAME=$(basename "$REL_PATH")
BASE_NAME="${FILE_NAME%.*}"

LOCAL_TS="$LOCAL_WORK_DIR/source_temp.ts"
LOCAL_MP4="$LOCAL_WORK_DIR/output_temp.mp4"

# 清理旧缓存
rm -f "$LOCAL_TS" "$LOCAL_MP4"

# 1. 下载
echo "Step 1: 下载中..."
rclone copyto "$REMOTE_NAME:$REMOTE_PATH/$REL_PATH" "$LOCAL_TS"

if [ ! -f "$LOCAL_TS" ]; then
echo "错误: 下载失败,跳过。"
continue
fi

# 2. 转码 (ts -> mp4)
echo "Step 2: 转码中..."
# -c:v copy 表示视频流直接复制不重新编码(速度快)
# -c:a aac 表示音频转为AAC以保证兼容性
ffmpeg -i "$LOCAL_TS" -c:v copy -c:a aac -strict experimental "$LOCAL_MP4" -y -hide_banner -loglevel error

if [ $? -eq 0 ] && [ -f "$LOCAL_MP4" ]; then
# 计算上传路径
if [ "$DIR_NAME" == "." ]; then
REMOTE_UPLOAD_PATH="$REMOTE_NAME:$REMOTE_PATH/$BASE_NAME.mp4"
else
REMOTE_UPLOAD_PATH="$REMOTE_NAME:$REMOTE_PATH/$DIR_NAME/$BASE_NAME.mp4"
fi

# 3. 上传
echo "Step 3: 上传至 [$REMOTE_UPLOAD_PATH]..."
rclone copyto "$LOCAL_MP4" "$REMOTE_UPLOAD_PATH"

if [ $? -eq 0 ]; then
# 4. 删除远程源文件
echo "Step 4: 删除远程源文件..."
rclone deletefile "$REMOTE_NAME:$REMOTE_PATH/$REL_PATH"
echo "完成。"
else
echo "错误: 上传失败 (可能是 403 权限问题),保留源文件。"
fi
else
echo "错误: FFmpeg 转码失败。"
fi

done

# 清理
rm -rf "$LOCAL_WORK_DIR"
unset IFS
echo "所有任务结束。"

5.3 保存与权限设置

  1. Ctrl+X,输入 y,按 Enter 保存退出。

  2. 修复换行符(防止从 Windows 复制导致的报错)

    1
    sed -i 's/\r$//' convert_ts.sh
  3. 赋予执行权限:

    1
    chmod +x convert_ts.sh

6. 测试与运行

手动测试

运行脚本查看输出日志:

1
./convert_ts.sh
  • 成功标志:显示 Step 1 下载 -> Step 2 转码 -> Step 3 上传 -> Step 4 删除,全程无 Error。
  • 常见错误
    • required file not found:请重新运行上面的 sed -i 命令。
    • Database Is Read Only:OneDrive 空间满了或账号被冻结,需登录网页版 OneDrive 处理。

7. 设置定时任务 (自动运行)

如果你希望服务器每天(例如凌晨 2 点)自动处理:

  1. 打开定时任务配置:

    1
    crontab -e
  2. 在文件末尾添加一行:

    1
    0 2 * * * /bin/bash /root/convert_ts.sh >> /root/convert_log.txt 2>&1

    (假设脚本在 /root 目录下,如果不是请修改路径)


8. 维护与排错

  • 查看日志:如果设置了定时任务,可以通过 cat /root/convert_log.txt 查看运行情况。
  • 调整转码质量:如果转换后的视频无法播放,请修改脚本中的 ffmpeg 命令,将 -c:v copy 改为 -c:v libx264(会显著增加 CPU 占用和转换时间,但兼容性最好)。
  • 空间管理:定期检查服务器 /tmp 目录,虽然脚本会清理,但以防万一。