Alby's blog

世上没有巧合,只有巧合的假象。

0%

Shell 调用 FFmpeg 进行定时启动和停止录制

一、概述

Shell 调用 FFmpeg 进行定时启动和停止录制。

二、单时段录制

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
#!/bin/bash

# 设定开始时间和结束时间(格式为HHMM)
start_time="0620"
end_time="0710"

# 转换为秒(这里只用于比较,实际不直接使用秒来计算)
start_hour=$((10#${start_time:0:2}))
start_min=$((10#${start_time:2:2}))
end_hour=$((10#${end_time:0:2}))
end_min=$((10#${end_time:2:2}))

# ffmpeg的PID变量
ffmpeg_pid=0

# 等待直到开始时间
while true; do
current_hour=$(date +%H)
current_min=$(date +%M)
if [ $current_hour -eq $start_hour ] && [ $current_min -eq $start_min ]; then
break
fi
echo "Waiting ffmpeg to start: $(date)"
sleep 60
done

# 启动ffmpeg并保存PID
echo "Starting ffmpeg..."
# 如果运行多份脚本并且启动录制的时间相同,请确保 output_filename 不会重名。
file_prefix=$(date +%Y%m%d)
output_filename="${file_prefix}_${start_time}_${end_time}.aac"
ffmpeg -i http://ngcdn001.cnr.cn/live/zgzs/index.m3u8 -vn -c:a copy "$output_filename" &
ffmpeg_pid=$!

# 等待直到结束时间或ffmpeg自然结束
while true; do
current_hour=$(date +%H)
current_min=$(date +%M)
if [ $current_hour -eq $end_hour ] && [ $current_min -eq $end_min ]; then
# 检查ffmpeg是否还在运行,并杀死它
if kill -0 $ffmpeg_pid 2>/dev/null; then
echo "Killing ffmpeg process with PID $ffmpeg_pid"
kill $ffmpeg_pid
else
# 如果运行多份脚本,下行的提示可以忽略。
echo "ffmpeg process with PID $ffmpeg_pid does not exist or has already been killed"
fi
break
fi

echo "Waiting ffmpeg to stop: $(date)"
sleep 60
done

echo "ffmpeg has been stopped or reached the end time."

多时段录制

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
#!/bin/bash

# 设定时间段列表,格式为"HHMM-HHMM"(开始时间-结束时间)
time_slots=("0625-0705" "1825-1905")

# 遍历时间段列表
for slot in "${time_slots[@]}"; do
# 分割开始时间和结束时间
start_time=${slot%-*}
end_time=${slot#*-}

# 转换为小时和分钟
start_hour=$((10#${start_time:0:2}))
start_min=$((10#${start_time:2:2}))
end_hour=$((10#${end_time:0:2}))
end_min=$((10#${end_time:2:2}))

# 等待直到开始时间
while true; do
current_hour=$(date +%H)
current_min=$(date +%M)
if [ $current_hour -eq $start_hour ] && [ $current_min -eq $start_min ]; then
break
fi
echo "Waiting for ${start_hour}:${start_min} to start ffmpeg: $(date)"
sleep 60
done

# 启动ffmpeg并保存PID
echo "Starting ffmpeg for ${start_hour}:${start_min} - ${end_hour}:${end_min}..."
# 如果运行多份脚本并且启动录制的时间相同,请确保 output_filename 不会重名。
file_prefix=$(date +%Y%m%d)
output_filename="${file_prefix}_${start_time}_${end_time}.aac"
ffmpeg -i http://ngcdn001.cnr.cn/live/zgzs/index.m3u8 -vn -c:a copy "$output_filename" &
ffmpeg_pid=$!

# 等待直到结束时间或ffmpeg自然结束
while true; do
current_hour=$(date +%H)
current_min=$(date +%M)
if [ $current_hour -eq $end_hour ] && [ $current_min -eq $end_min ]; then
# 检查ffmpeg是否还在运行,并杀死它
if kill -0 $ffmpeg_pid 2>/dev/null; then
echo "Killing ffmpeg process with PID $ffmpeg_pid"
kill $ffmpeg_pid
else
# 如果运行多份脚本,下行的提示可以忽略。
echo "ffmpeg process with PID $ffmpeg_pid does not exist or has already been killed"
fi
break
fi

echo "Waiting for ffmpeg to stop or ${end_hour}:${end_min}: $(date)"
sleep 60
done
done

echo "All ffmpeg sessions have been stopped or reached their end times."