2013-01-03 98 views
12

我正在寻找一个解决方案,无论是在Linux或Windows中,可以让我如何捕捉Python中的视频(和音频),从相机(或摄像头)

  • 录制视频( +音频)从我的摄像头&麦克风,同时。
  • 保存为一个file.AVI(或MPG或其他)
  • 显示屏幕上的视频,同时记录其

压缩不是在我的情况的问题,其实我更喜欢拍摄RAW并在稍后压缩。

到目前为止,我已经完成了它在VB中的一个ActiveX组件,它负责处理所有事情,并且我想用python进行处理(VB解决方案不稳定,不可靠)。

迄今为止我见过的代码,只捕捉视频,或单独的帧...

我在

  • 的OpenCV所以远远看去 - 找不到音频采集有
  • PyGame - 没有同步音频捕捉(AFAIK)
  • VideoCapture - 只提供单帧。
  • SimpleCV - 没有音讯
  • VLC - 结合VideoLAN的程序进入wxPthon - 希望它会做(仍在调查此选项)
  • kivy - 只是听说过,没能得到它在Windows下工作,所以远。

的问题 - 是有蟒蛇视频&音频捕获库?

或 - 如果有其他选项,还有什么?

回答

2

我会推荐ffmpeg。有一个python包装。

http://code.google.com/p/pyffmpeg/

+0

我没有看到如何ffmpeg也可以用来显示视频,而它被记录。 (例如,可以将vlc嵌入到wxpython中,或者作为独立的无边框窗口) –

1

我一直在四处寻找一个很好的答案,我认为这是GStreamer ...

为python绑定的文档是非常轻,而且大部分似乎以旧版0.10 GStreamer为主,而不是新版1.X版本,但GStreamer是一个功能非常强大的跨平台多媒体框架,可以对任何内容进行流,多路复用,转码和显示。

+0

我不再需要这个了,但无论如何感谢您 –

11

答案:没有。在Python中没有单一的库/解决方案来同时进行视频/音频记录。您必须分开实施这两种解决方案,并以智能方式合并音频和视频信号,最终形成视频/音频文件。

我为您提出的问题得到了解决方案。我的代码解决了您的三个问题:

  • 同时记录来自网络摄像头和麦克风的视频和音频。
  • 它将最终的视频/音频文件保存为。AVI
  • 取消注释行76,77和78将使视频在录制时显示为屏幕。

我的解决方案使用pyaudio音频录制,opencv视频录制,并为ffmpeg路复用两个信号。为了能够同时记录,我使用多线程。一个线程记录视频,另一个线程记录音频。我已经将我的代码上传到github,并且在这里包含了所有必要的部分。

https://github.com/JRodrigoF/AVrecordeR

注:opencv是不是能够控制在该网络摄像头做了记录帧率。它只能在文件的编码中指定所需的最终帧数,但是网络摄像机通常根据规格和光线条件(我发现)有不同的表现。所以fps必须在代码级别进行控制。

import cv2 
import pyaudio 
import wave 
import threading 
import time 
import subprocess 
import os 

class VideoRecorder(): 

    # Video class based on openCV 
    def __init__(self): 

     self.open = True 
     self.device_index = 0 
     self.fps = 6    # fps should be the minimum constant rate at which the camera can 
     self.fourcc = "MJPG"  # capture images (with no decrease in speed over time; testing is required) 
     self.frameSize = (640,480) # video formats and sizes also depend and vary according to the camera used 
     self.video_filename = "temp_video.avi" 
     self.video_cap = cv2.VideoCapture(self.device_index) 
     self.video_writer = cv2.VideoWriter_fourcc(*self.fourcc) 
     self.video_out = cv2.VideoWriter(self.video_filename, self.video_writer, self.fps, self.frameSize) 
     self.frame_counts = 1 
     self.start_time = time.time() 


    # Video starts being recorded 
    def record(self): 

#  counter = 1 
     timer_start = time.time() 
     timer_current = 0 


     while(self.open==True): 
      ret, video_frame = self.video_cap.read() 
      if (ret==True): 

        self.video_out.write(video_frame) 
#     print str(counter) + " " + str(self.frame_counts) + " frames written " + str(timer_current) 
        self.frame_counts += 1 
#     counter += 1 
#     timer_current = time.time() - timer_start 
        time.sleep(0.16) 
#     gray = cv2.cvtColor(video_frame, cv2.COLOR_BGR2GRAY) 
#     cv2.imshow('video_frame', gray) 
#     cv2.waitKey(1) 
      else: 
       break 

       # 0.16 delay -> 6 fps 
       # 


    # Finishes the video recording therefore the thread too 
    def stop(self): 

     if self.open==True: 

      self.open=False 
      self.video_out.release() 
      self.video_cap.release() 
      cv2.destroyAllWindows() 

     else: 
      pass 


    # Launches the video recording function using a thread   
    def start(self): 
     video_thread = threading.Thread(target=self.record) 
     video_thread.start() 





class AudioRecorder(): 


    # Audio class based on pyAudio and Wave 
    def __init__(self): 

     self.open = True 
     self.rate = 44100 
     self.frames_per_buffer = 1024 
     self.channels = 2 
     self.format = pyaudio.paInt16 
     self.audio_filename = "temp_audio.wav" 
     self.audio = pyaudio.PyAudio() 
     self.stream = self.audio.open(format=self.format, 
             channels=self.channels, 
             rate=self.rate, 
             input=True, 
             frames_per_buffer = self.frames_per_buffer) 
     self.audio_frames = [] 


    # Audio starts being recorded 
    def record(self): 

     self.stream.start_stream() 
     while(self.open == True): 
      data = self.stream.read(self.frames_per_buffer) 
      self.audio_frames.append(data) 
      if self.open==False: 
       break 


    # Finishes the audio recording therefore the thread too  
    def stop(self): 

     if self.open==True: 
      self.open = False 
      self.stream.stop_stream() 
      self.stream.close() 
      self.audio.terminate() 

      waveFile = wave.open(self.audio_filename, 'wb') 
      waveFile.setnchannels(self.channels) 
      waveFile.setsampwidth(self.audio.get_sample_size(self.format)) 
      waveFile.setframerate(self.rate) 
      waveFile.writeframes(b''.join(self.audio_frames)) 
      waveFile.close() 

     pass 

    # Launches the audio recording function using a thread 
    def start(self): 
     audio_thread = threading.Thread(target=self.record) 
     audio_thread.start() 





def start_AVrecording(filename): 

    global video_thread 
    global audio_thread 

    video_thread = VideoRecorder() 
    audio_thread = AudioRecorder() 

    audio_thread.start() 
    video_thread.start() 

    return filename 




def start_video_recording(filename): 

    global video_thread 

    video_thread = VideoRecorder() 
    video_thread.start() 

    return filename 


def start_audio_recording(filename): 

    global audio_thread 

    audio_thread = AudioRecorder() 
    audio_thread.start() 

    return filename 




def stop_AVrecording(filename): 

    audio_thread.stop() 
    frame_counts = video_thread.frame_counts 
    elapsed_time = time.time() - video_thread.start_time 
    recorded_fps = frame_counts/elapsed_time 
    print "total frames " + str(frame_counts) 
    print "elapsed time " + str(elapsed_time) 
    print "recorded fps " + str(recorded_fps) 
    video_thread.stop() 

    # Makes sure the threads have finished 
    while threading.active_count() > 1: 
     time.sleep(1) 


# Merging audio and video signal 

    if abs(recorded_fps - 6) >= 0.01: # If the fps rate was higher/lower than expected, re-encode it to the expected 

     print "Re-encoding" 
     cmd = "ffmpeg -r " + str(recorded_fps) + " -i temp_video.avi -pix_fmt yuv420p -r 6 temp_video2.avi" 
     subprocess.call(cmd, shell=True) 

     print "Muxing" 
     cmd = "ffmpeg -ac 2 -channel_layout stereo -i temp_audio.wav -i temp_video2.avi -pix_fmt yuv420p " + filename + ".avi" 
     subprocess.call(cmd, shell=True) 

    else: 

     print "Normal recording\nMuxing" 
     cmd = "ffmpeg -ac 2 -channel_layout stereo -i temp_audio.wav -i temp_video.avi -pix_fmt yuv420p " + filename + ".avi" 
     subprocess.call(cmd, shell=True) 

     print ".." 




# Required and wanted processing of final files 
def file_manager(filename): 

    local_path = os.getcwd() 

    if os.path.exists(str(local_path) + "/temp_audio.wav"): 
     os.remove(str(local_path) + "/temp_audio.wav") 

    if os.path.exists(str(local_path) + "/temp_video.avi"): 
     os.remove(str(local_path) + "/temp_video.avi") 

    if os.path.exists(str(local_path) + "/temp_video2.avi"): 
     os.remove(str(local_path) + "/temp_video2.avi") 

    if os.path.exists(str(local_path) + "/" + filename + ".avi"): 
     os.remove(str(local_path) + "/" + filename + ".avi") 
+0

您知道这是否可以在Python 3.x(理想情况下为3.4)下工作? –

+0

如何支持mac os? – Gank

+0

我不知道这里使用的库是否也可用于python 3. – JRodrigoF

相关问题