美文网首页
python按照一定间隔提取视频帧,分离视频中的音频

python按照一定间隔提取视频帧,分离视频中的音频

作者: 牛奶大泡芙 | 来源:发表于2019-10-22 16:03 被阅读0次

最近开发项目涉及到将mp4视频中的音频提取出来,进行分割;提取视频中的视频帧,间隔60s,用于鉴别视频中的内容信息是否合规。
其实两者共同的原理是,将视频(音频)读出来,获取模块提供的参数,主要是频率,乘以我们理想的时间间隔,就得到了我们在循环处理数据时候的除数,在循环的若干特定时刻拦截需要的数据。
这里用的cv2,安装命令:

pip install opencv-python

官网中这样描述

**a.** Packages for standard desktop environments (Windows, macOS, almost any GNU/Linux distribution)

*   run `pip install opencv-python` if you need only main modules
*   run `pip install opencv-contrib-python` if you need both main and contrib modules (check extra modules listing from [OpenCV documentation](https://docs.opencv.org/master/))

关于提取视频帧还有一种方法,skimage,但是提取的时候出现了内存不足的问题,小编没有深究问题的原因,选择了另一种方案,以下代码可以参考

from moviepy.editor import *
import wave
import numpy as np
import pylab
import skimage
import imageio
import cv2

# imageio.plugins.ffmpeg.download()
# 本文件的功能是将视频中的音频每分钟生成一个文件,保存成音频文件 在testresult文件夹中
# 视频播放每一分钟,获取视频中的一帧,存成图片 在videoframe文件夹中


def get_audio(video_path='test.mp4', audio_path='test.wav'):
    """
    提取视频中的音频,存为audio_path
    :str video_path: 视频的地址
    :str audio_path: 提取的音频地址
    :None:
    """
    # moviepy.VideoFileClip: 读取视频到内存,返回一个VideoFileClip的对象
    video = VideoFileClip(video_path)
    # 获取视频的音频部分
    audio = video.audio
    # 将视频中的音频部分提取出来,写入test.mp3
    audio.write_audiofile(audio_path)


CutTimeDef = 60  # 以60s截断文件
new_path = 'test.wav'


def cut_file(audio_path='test.wav'):
    """
    把音频以60s为长度切割
    :str audio_path: 音频文件的地址
    :None:
    """
    FileName = audio_path
    print("CutFile File Name is ", FileName)
    f = wave.open(r"" + FileName, "rb")
    params = f.getparams()
    print(params)
    nchannels, sampwidth, framerate, nframes = params[:4]
    # 60s内的采样次数
    CutFrameNum = framerate * CutTimeDef
    # 读取格式信息
    # 一次性返回所有的WAV文件的格式信息,它返回的是一个元组(tuple):声道数, 量化位数(byte    单位), 采
    # 样频率, 采样点数, 压缩类型, 压缩类型的描述。wave模块只支持非压缩的数据,因此可以忽略最后两个信息
    # nchannels: 声道数
    # sampwidth: 量化位数(byte)
    # framerate: 采样频率
    # nframes: 采样点数

    print("CutFrameNum=%d" % (CutFrameNum))
    print("nchannels=%d" % (nchannels))
    print("sampwidth=%d" % (sampwidth))
    print("framerate=%d" % (framerate))
    print("nframes=%d" % (nframes))
    # readframes读取音频数据,nframes指定需要读取的长度(整个音频的采样点数)(以取样点为单位)
    str_data = f.readframes(nframes)
    f.close()  # 将波形数据转换成数组
    # 需要根据声道数和量化单位,将读取的二进制数据转换为一个可以计算的数组
    wave_data = np.fromstring(str_data, dtype=np.short)
    wave_data.shape = -1, 2
    wave_data = wave_data.T
    temp_data = wave_data.T
    StepNum = CutFrameNum
    StepTotalNum = 0
    haha = 0
    while StepTotalNum < nframes:
        print("Stemp=%d" % (haha))
        audio_name = ".\\testresult\\" + FileName[-17:-4] + "-" + str(haha + 1) + ".wav"
        print(audio_name)
        temp_dataTemp = temp_data[StepNum * (haha):StepNum * (haha + 1)]
        haha = haha + 1
        StepTotalNum = haha * StepNum
        temp_dataTemp.shape = 1, -1
        temp_dataTemp = temp_dataTemp.astype(np.short)  # 打开WAV文档
        f = wave.open(audio_name, "wb")  #
        # 配置声道数、量化位数和取样频率
        f.setnchannels(nchannels)
        f.setsampwidth(sampwidth)
        f.setframerate(framerate)
        # 将wav_data转换为二进制数据写入文件
        f.writeframes(temp_dataTemp.tostring())
        f.close()


def extract_frame(input_path='test.mp4'):
    """
    以60s为间隔提取视频帧,并将其作为图片保存
    :str input_path:
    :None:
    """
    vc = cv2.VideoCapture(input_path)
    c = 1
    if vc.isOpened():
        rval, frame = vc.read()
    else:
        rval = False
    time_interval = 60
    # 视频采样的间隔是60s,vc.get(5)获得帧频,CV_CAP_PROP_FPS
    timeF = vc.get(5) * time_interval
    count = 0
    while rval:
        print(c)
        rval, frame = vc.read()
        if c%timeF == 0:
            cv2.imwrite(".\\videoframe\\" + str(count) + ".jpg", frame)
            count += 1
        c += 1
        cv2.waitKey(1)
    vc.release()


if __name__ == '__main__':
    # get_audio()
    # cut_file()
    extract_frame()


相关文章

网友评论

      本文标题:python按照一定间隔提取视频帧,分离视频中的音频

      本文链接:https://www.haomeiwen.com/subject/qmwqvctx.html