美文网首页
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