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
| import subprocess
| import os
|
| def test_pipeline_to_multiple_slices(video_path):
| frame_segments = [(0, 60), (60, 79), (79, 98), (98, 116), (116, 135),
| (135, 153), (153, 172), (172, 190), (190, 209),
| (209, 228), (228, 247), (247, 266), (266, 285), (285, 305)] # 帧区间
|
| # 启动 FFmpeg 以读取视频帧数据并通过管道输出
| ffmpeg_extract = [
| "ffmpeg", "-i", video_path, "-vf", "fps=30", "-f", "image2pipe", "-vcodec", "png", "-"
| ]
| process_extract = subprocess.Popen(ffmpeg_extract, stdout=subprocess.PIPE, bufsize=10**8) # 使用较大缓冲区
|
| # 创建多个子进程,处理视频切片
| slice_processes = []
| output_pipes = []
|
| for i, (start_frame, end_frame) in enumerate(frame_segments):
| output_file = f"slice_{i+1}.mp4"
| ffmpeg_encode = [
| "ffmpeg", "-framerate", "30", "-f", "image2pipe", "-vcodec", "png", "-i", "-",
| "-c:v", "libx264", "-preset", "slow", "-crf", "0", "-pix_fmt", "yuv420p", output_file
| ]
| process = subprocess.Popen(ffmpeg_encode, stdin=subprocess.PIPE)
| slice_processes.append(process)
| output_pipes.append((process.stdin, start_frame, end_frame))
|
| current_frame = 0
|
| try:
| while True:
| frame_data = process_extract.stdout.read(1024*1024) # 每次读取 1MB,直到无数据
| if not frame_data:
| break # 当读取到视频结束时跳出循环
|
| # 分发帧数据到合适的子进程
| for pipe, start_frame, end_frame in output_pipes:
| if start_frame <= current_frame < end_frame:
| pipe.write(frame_data) # 写入帧数据
| break
|
| current_frame += 1
|
| finally:
| # 关闭所有子进程的输入流
| for pipe, _, _ in output_pipes:
| pipe.close()
|
| # 等待所有子进程完成
| for process in slice_processes:
| process.wait()
|
| # 关闭提取进程的输出流
| process_extract.stdout.close()
| process_extract.wait()
|
| if __name__ == "__main__":
| video_path = "E:/抖音-AI风景/Test/demo.mp4"
| test_pipeline_to_multiple_slices(video_path)
|
|