前几天故宫博物院的单霁翔老师来天津做讲座,但是很遗憾讲座名额有限,没有机会亲临现场聆听老先生的讲演。
但是好在同事对现场录音和拍照,看了一下录音和照片的时间戳,大致可以合的上,因此萌生出把照片和录音合并在一起的想法。
不说废话,码上开干。
起初的思路是用ffmpeg库把照片按照关键帧的顺序插进音频中,合成完整的视频。但是玩过视频的人都知道,这么做是不可能成立的。
于是调整思路,先把照片时间戳找出来,构建字典,key是时间戳,value是照片名称。然后就用到了传说的opencv,按照音频/照片序列时长,生成avi文件。当然,这时的avi文件很大,有一个多G,没关系,后面用ffmpeg压缩一下转成了49m的mp4文件。
现在有了视频文件,然后在ffmpeg中把录音和这个合成的视频文件合并一下就可以了。代码如下:

# -*- coding: utf-8 -*-
import exifread
import os
import json
import time
import subprocess
import cv2
from cv2 import VideoWriter, VideoWriter_fourcc, imread, resizedef getexiftime(imgname):'''get the exif info of image'''with open(imgname, 'rb') as f:tags = exifread.process_file(f, stop_tag='Image DateTime')# tags['Image DateTime'].values = "2019:12:19 14:26:00"imgtimestamp = time.strptime(tags['Image DateTime'].values, '%Y:%m:%d %H:%M:%S')imgtimestamp = time.mktime(imgtimestamp)return imgtimestamp  # like 1576736760def maketimedict(path):'''make a dict ,key is the imgtimestamp, value is the name of imagepath: dir of images, string'''res = dict()for item in os.listdir(path):imgpath = f'{path}/{item}'if os.path.isfile(imgpath):try:imgtimestamp = getexiftime(imgpath)key = int(float(imgtimestamp))res.setdefault(key, item)except Exception:continuereturn resdef savejson(imgdict, outfile):'''save the imgdict as a json file'''with open(outfile, 'w') as fp:json.dump(imgdict, fp)return outfiledef loadjson(infile):'''load the json file as dictbut the key will turn to string'''with open(infile, 'r') as fp:res = json.load(fp)return resdef combinevideo(invideodir, inaudiodir):outputfile = "output.mp4"command1 = f"ffmpeg -i {invideodir} test.mp4"# 压缩视频文件subprocess.call(command1)command2 = f"ffmpeg -i test.mp4 -i {inaudiodir} -c:v copy -c:a aac -strict experimental {outputfile}"# 合并视频音频subprocess.call(command2)return outputfiledef makevideo(imgdict, imgdir):'''combine the images to video, no audioimgdict: keys:time, values:img nameimgdir: dir of images'''audiostart = 1576736760audioend = 1576745959imgstart = min(imgdict.keys())  # 1576737005imgend = max(imgdict.keys())  # 1576746028imgdir = "../images/"outdir = "./test.avi"count_frames = max([imgend, audioend]) - min([imgstart, audiostart]) + 1fps = 1size = (640, 480)fourcc = VideoWriter_fourcc(*"MJPG")videowriter = cv2.VideoWriter(outdir, fourcc, fps, size)inputstr = imgdir + imgdict[imgstart]for i in range(count_frames):im_key = min([imgstart, audiostart]) + iim_name = imgdict.get(im_key)if im_name:inputstr = imgdir + im_nameprint(inputstr, 'time is ', im_key, i/count_frames*100, '%')frame = imread(inputstr)frame = resize(frame, size)videowriter.write(frame)videowriter.release()return outdirdef main():imgdir = "../images"imgdict = maketimedict(imgdir)savejson(imgdict, 'imgtime.json')  # 存一下,以防万一makevideo(imgdict, imgdir)  # 生成中间文件,test.aviinvideodir = "test.avi"inaudiodir = "../audio/191219_001.mp3"combinevideo(invideodir, inaudiodir)  # 生成最终合成文件, output.mp4if __name__ == "__main__":main()

把会议记录的照片和音频合成一个视频文件(python+ffmpeg)相关推荐

  1. 嵌入式端音频开发(实战篇)之 4.2 把很多音频合成一个bin文件并统计每个音频文件的大小的方法(内含转换脚本)

    查看本系列全部文章请点击:嵌入式端音频开发系列汇总(持续更新) 查看本文全部内容:嵌入式端音频开发(实战篇)之 4.2 把很多音频合成一个bin文件并统计每个音频文件的大小的方法(内含转换脚本) 文件 ...

  2. python播放本地视频_python opencv 读取本地视频文件 修改ffmpeg的方法

    Python + opencv 读取视频的三种情况: 情况一:通过摄像头采集视频 情况二:通过本地视频文件获取视频 情况三:通过摄像头录制视频,再读取录制的视频 摄像头采集.本地视频文件的读取.写视频 ...

  3. python怎么创建txt文件夹_python怎么创建一个txt文件/python创建文件夹基础教程

    python怎么创建一个txt文件 python怎么创建一个txt文方法. 如考: 1.首先内置的空闲编辑器进行编辑(单击并选择copy),如下图所示. 2.您可以下载记事本和其他编辑软件,以支持多种 ...

  4. 使用FFmpeg工具将一个图片和一个音频合成一个视频以及在window系统下使用脚本运行

    注意:使用命令前检查正在使用的电脑是否安装的有ffmpeg工具以及是否配置环境变量. 命令: ffmpeg -r 10 -f image2 -loop 1 -i F:\javatest\3.jpg - ...

  5. 更改一个视频文件夹下视频文件的文件名

    2019独角兽企业重金招聘Python工程师标准>>> 在电脑D盘的ComputerScience文件夹中有JDBC视频教程文件夹(图片中的副本是实验时保存的一份,以防失误后视频丢失 ...

  6. 怎么查看一个视频文件的清晰度和详细参数

    一.现象: 我们每个人在看视频时通常都会关心一个重要参数,清晰度!特别是显示器和显卡较好的朋友们,当然希望能下载一个清晰度较高的视频发挥显示器和显卡的作用. 但是,视频网站上每一部电影都有几种不同的格 ...

  7. 如何最大效率压缩视频文件(ffmpeg)

    转载并翻译,原文:stackexchange 我测试了针对这个问题提出的大多数其他答案,测试数据结论如下.以下是我测试的方法: (BR)修改码率 # $infile: 输入视频路径 # $outfil ...

  8. 如何将Dicom系列转换为一个Nifti文件(Python)

    简介 在医学成像中,我们通常使用两种类型的图像,Dicom或Nifti.但这两种类型的图像(或者说文件)之间是有区别的,因为它们比普通图像有更多的信息.这些信息存储在同一个文件中,Dicom 或是Ni ...

  9. python创建一个txt文件-python中如何创建一个txt文件

    python中有一个内置函数open(),该函数用于打开一个文件,创建一个 file 对象,相关的方法才可以调用它进行读写.如果以只写模式打开一个文件,那么该函数会在文件不存在时创建一个文件. 语法: ...

最新文章

  1. 通过手写Spring MVC来理解其原理
  2. C#获取指定坐标点像素,效率更高快
  3. 深入理解 js 之继承与原型链
  4. python响铃符不响_python语法注意事项
  5. Asp.Net就业课堂之模板控件
  6. origin tangent插件_如何用origin绘制切线
  7. 孪生再世代表数字几_工信部发布数字孪生应用白皮书:特斯联入选智慧城市建设标杆案例...
  8. Fiddler抓包【3】_设置断点修改
  9. C#实现小写金额转大写金额
  10. 国际短信平台哪家好?
  11. 设置全局键盘钩子和消息钩子
  12. manjaro设置字体_Manjaro 20.03字体美化的2.5个级别
  13. [SAS Hard Coding] 车型对应车商代码
  14. [云原生专题-24]:K8S - Kubernetes(K8S)Master集群构建与安装过程详细解读 - 初始控制节点的安装
  15. Android自定义控件:NestedScrolling实现仿魅族flyme6应用市场应用详情弹出式layout
  16. 【论文写作】Latex在线创作工具overleaf及账号注册办法
  17. 谁说国内无RISC-V开源核——您还不知蜂鸟E200?
  18. 区块链技术开发公司谈区块链如何优化产业链
  19. pg备份还原工具--pg_rman
  20. 拆解IncServer网络库

热门文章

  1. 重装win10系统.
  2. CryptEncrypt 和CryptDecrypt 的使用
  3. 云时代数据科学平台--Sengee
  4. 2010 Oct MVP Open Day
  5. Node.js笔记:SerialPort(串口)模块使用(基于9.x.x)
  6. 虚拟机与主机共享文件夹的实现
  7. Mybatis-Mapper.xml输入输出映射
  8. JAVA - 根据指定 excel 模板填充数据后导出
  9. html设置抽奖概率,在线抽奖大转盘和概率计算
  10. Linux解压torrent文件命令,linux版uTorrent安装手记