当前位置:   article > 正文

Python 多个视频拼接成一个视频工具(附代码) | Python工具_python 实现360视频拼接开源代码

python 实现360视频拼接开源代码

目录

前言

环境依赖

代码

总结


前言

本文提供将多个视频拼接为一个视频的Python工具代码,其中有一些限制条件,下面的代码说明会提到。

环境依赖

  ffmpeg环境安装,可以参考我的另一篇文章:windows ffmpeg安装部署_阿良的博客-CSDN博客

本文主要使用到的不是ffmpeg,而是ffprobe也在上面这篇文章中的zip包中。

ffmpy安装:

pip install ffmpy -i https://pypi.douban.com/simple

代码

不废话了,上代码。

  1. #!/user/bin/env python
  2. # coding=utf-8
  3. """
  4. @project : csdn
  5. @author : 剑客阿良_ALiang
  6. @file : concat_video.py
  7. @ide : PyCharm
  8. @time : 2021-12-23 15:23:16
  9. """
  10. from ffmpy import FFmpeg
  11. import os
  12. import uuid
  13. import subprocess
  14. # 视频拼接
  15. def concat(video_list: list, output_dir: str):
  16. if len(video_list) == 0:
  17. raise Exception('video_list can not empty')
  18. _ext = check_format(video_list)
  19. _fps = check_fps(video_list)
  20. _result_path = os.path.join(
  21. output_dir, '{}{}'.format(
  22. uuid.uuid1().hex, _ext))
  23. _tmp_config = make_tmp_concat_config(video_list, output_dir)
  24. ff = FFmpeg(inputs={'{}'.format(_tmp_config): '-f concat -safe 0 -y'}, outputs={
  25. _result_path: '-c copy'})
  26. print(ff.cmd)
  27. ff.run()
  28. os.remove(_tmp_config)
  29. return _result_path
  30. # 构造拼接所需临时文件
  31. def make_tmp_concat_config(video_list: list, output_dir: str):
  32. _tmp_concat_config_path = os.path.join(output_dir, '{}.txt'.format(uuid.uuid1().hex))
  33. with open(_tmp_concat_config_path, mode='w', encoding='utf-8') as f:
  34. f.writelines(list(map(lambda x: 'file {}\n'.format(x), video_list)))
  35. return _tmp_concat_config_path
  36. # 校验每个视频的格式
  37. def check_format(video_list: list):
  38. _video_format = ''
  39. for x in video_list:
  40. _ext = os.path.splitext(x)[-1]
  41. if _video_format == '' and _ext != '':
  42. _video_format = _ext
  43. continue
  44. if _video_format != '' and _ext == _video_format:
  45. continue
  46. if _video_format != '' and _ext != _video_format:
  47. raise Exception('Inconsistent video format')
  48. return _video_format
  49. # 校验每个视频的fps
  50. def check_fps(video_list: list):
  51. _video_fps = 0
  52. for x in video_list:
  53. _fps = get_video_fps(x)
  54. if _video_fps == 0 and _fps:
  55. _video_fps = _fps
  56. continue
  57. if _video_fps != 0 and _fps == _video_fps:
  58. continue
  59. if _video_fps != '' and _fps != _video_fps:
  60. raise Exception('Inconsistent video fps')
  61. if _video_fps == 0:
  62. raise Exception('video fps error')
  63. return _video_fps
  64. # 获取视频fps
  65. def get_video_fps(video_path: str):
  66. ext = os.path.splitext(video_path)[-1]
  67. if ext != '.mp4' and ext != '.avi' and ext != '.flv':
  68. raise Exception('format not support')
  69. ffprobe_cmd = 'ffprobe -v error -select_streams v -of default=noprint_wrappers=1:nokey=1 -show_entries stream=r_frame_rate {}'
  70. p = subprocess.Popen(
  71. ffprobe_cmd.format(video_path),
  72. stdout=subprocess.PIPE,
  73. stderr=subprocess.PIPE,
  74. shell=True)
  75. out, err = p.communicate()
  76. print("subprocess 执行结果:out:{} err:{}".format(out, err))
  77. fps_info = str(out, 'utf-8').strip()
  78. if fps_info:
  79. if fps_info.find("/") > 0:
  80. video_fps_str = fps_info.split('/', 1)
  81. fps_result = int(int(video_fps_str[0]) / int(video_fps_str[1]))
  82. else:
  83. fps_result = int(fps_info)
  84. else:
  85. raise Exception('get fps error')
  86. return fps_result
  87. if __name__ == '__main__':
  88. print(concat(['D:/tmp/100.mp4', 'D:/tmp/101.mp4'], 'C:/Users/huyi/Desktop'))

代码说明

1、主要拼接方法为concat,入参分别为:视频列表、输出目录。

2、该视频拼接命令对视频本身有所限制,需要保证都是相同格式的视频,其次是每个视频的fps得一致,不然最终合成的视频会无法打开或者出现花屏现象。

3、临时的拼接文件会在使用后删除。

4、最终输出的文件名为了保证唯一使用uuid

验证一下

下面是我准备的两个视频:

执行结果

  1. PyDev console: starting.
  2. Python 3.6.13 |Anaconda, Inc.| (default, Mar 16 2021, 11:37:27) [MSC v.1916 64 bit (AMD64)] on win32
  3. runfile('D:/spyder/csdn/tool/concat_video.py', wdir='D:/spyder/csdn/tool')
  4. subprocess 执行结果:out:b'25/1\r\n' err:b''
  5. subprocess 执行结果:out:b'25/1\r\n' err:b''
  6. ffmpeg -f concat -safe 0 -y -i C:/Users/huyi/Desktop\6d02df4b63d111eca6eee454e8bf1461.txt -c copy C:/Users/huyi/Desktop\6d02df4a63d111ec9dbbe454e8bf1461.mp4
  7. ffmpeg version n4.3.1-20-g8a2acdc6da Copyright (c) 2000-2020 the FFmpeg developers
  8. built with gcc 9.3-win32 (GCC) 20200320
  9. configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --enable-iconv --enable-zlib --enable-libxml2 --enable-libfreetype --enable-libfribidi --enable-gmp --enable-lzma --enable-fontconfig --enable-libvmaf --disable-vulkan --enable-libvorbis --enable-amf --enable-libaom --enable-avisynth --enable-libdav1d --enable-ffnvcodec --enable-cuda-llvm --disable-libglslang --enable-libass --enable-libbluray --enable-libmp3lame --enable-libopus --enable-libtheora --enable-libvpx --enable-libwebp --enable-libmfx --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librav1e --enable-schannel --enable-sdl2 --enable-libsoxr --enable-libsrt --enable-libtwolame --enable-libvidstab --enable-libx264 --enable-libx265 --enable-libxvid --enable-libzimg --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-ldflags=-pthread --extra-libs=-lgomp
  10. libavutil 56. 51.100 / 56. 51.100
  11. libavcodec 58. 91.100 / 58. 91.100
  12. libavformat 58. 45.100 / 58. 45.100
  13. libavdevice 58. 10.100 / 58. 10.100
  14. libavfilter 7. 85.100 / 7. 85.100
  15. libswscale 5. 7.100 / 5. 7.100
  16. libswresample 3. 7.100 / 3. 7.100
  17. libpostproc 55. 7.100 / 55. 7.100
  18. [mov,mp4,m4a,3gp,3g2,mj2 @ 000001de4a7aebc0] Auto-inserting h264_mp4toannexb bitstream filter
  19. Input #0, concat, from 'C:/Users/huyi/Desktop\6d02df4b63d111eca6eee454e8bf1461.txt':
  20. Duration: N/A, start: -0.064000, bitrate: 1098 kb/s
  21. Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 16000 Hz, mono, fltp, 69 kb/s
  22. Metadata:
  23. handler_name : SoundHandler
  24. Stream #0:1(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1080x1920, 1028 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc
  25. Metadata:
  26. handler_name : VideoHandler
  27. Output #0, mp4, to 'C:/Users/huyi/Desktop\6d02df4a63d111ec9dbbe454e8bf1461.mp4':
  28. Metadata:
  29. encoder : Lavf58.45.100
  30. Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p, 1080x1920, q=2-31, 1028 kb/s, 25 fps, 25 tbr, 12800 tbn, 12800 tbc
  31. Metadata:
  32. handler_name : VideoHandler
  33. Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 16000 Hz, mono, fltp, 69 kb/s
  34. Metadata:
  35. handler_name : SoundHandler
  36. Stream mapping:
  37. Stream #0:1 -> #0:0 (copy)
  38. Stream #0:0 -> #0:1 (copy)
  39. Press [q] to stop, [?] for help
  40. [mov,mp4,m4a,3gp,3g2,mj2 @ 000001de4a7aebc0] Auto-inserting h264_mp4toannexb bitstream filter
  41. [mp4 @ 000001de4acdabc0] Non-monotonous DTS in output stream 0:1; previous: 6176768, current: 6176608; changing to 6176769. This may result in incorrect timestamps in the output file.
  42. frame=22199 fps=0.0 q=-1.0 Lsize= 119649kB time=00:14:48.05 bitrate=1103.7kbits/s speed=2.41e+03x
  43. video:111571kB audio:7524kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.465183%
  44. C:/Users/huyi/Desktop\6d02df4a63d111ec9dbbe454e8bf1461.mp4

 

结果验证

总结

视频拼接的限制还是有点多的。

分享:

        我们这种平凡之人在面对胜负关键时,总需要找寻某种倚靠,但,在比赛中乃是孤独的,无法倚靠任何人,那么,该倚靠什么呢?我想,只有自己曾经努力过的事实。 ——《东野圭吾》

如果本文对你有帮助的话,点个赞吧,谢谢!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/80560
推荐阅读
相关标签
  

闽ICP备14008679号