2013-01-03 60 views
12

tôi đang tìm kiếm một giải pháp, hoặc trong linux hoặc trong các cửa sổ, cho phép tôi đểLàm thế nào để chụp một đoạn video (AND audio) trong python, từ một máy ảnh (hoặc webcam)

  • quay video (+ âm thanh) từ webcam của tôi & micrô, đồng thời.
  • tiết kiệm nó như là một file.AVI (hoặc mpg hoặc bất cứ điều gì)
  • màn hình video trên màn hình trong khi quay nó

nén là không một vấn đề trong trường hợp của tôi, và tôi thực sự thích chụp RAW và nén nó sau.

Cho đến nay tôi đã thực hiện nó với một thành phần ActiveX trong VB mà đã chăm sóc của tất cả mọi thứ, và tôi muốn tiến bộ với python (giải pháp VB là không ổn định, không đáng tin cậy).

cho đến nay tôi đã nhìn thấy mã mà chỉ chụp VIDEO, hoặc khung cá nhân ...

Tôi đã nhìn cho đến nay tại

  • OpenCV - không thể tìm thấy âm thanh chụp có
  • PyGame - không ghi lại âm thanh đồng thời (AFAIK)
  • VideoCapture - chỉ cung cấp các khung hình duy nhất.
  • SimpleCV - không có âm thanh
  • VLC - liên kết với chương trình VideoLAN vào wxPthon - hy vọng nó sẽ làm (vẫn đang điều tra tùy chọn này)
  • kivy - chỉ nghe nói về nó, không quản lý để làm cho nó làm việc dưới cửa sổ SO XA.

Câu hỏi - có video & thư viện chụp âm thanh cho python không?

hoặc - các tùy chọn khác nếu có là gì?

Trả lời

2

Tôi muốn giới thiệu ffmpeg. Có một trình bao bọc python.

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

+0

tôi không thấy cách ffmpeg cũng có thể được sử dụng để hiển thị video trong khi đang được ghi lại. (ví dụ: có thể nhúng vlc vào wxpython hoặc cửa sổ không biên giới độc lập) –

1

Tôi đã tìm kiếm xung quanh cho một câu trả lời tốt việc này, và tôi nghĩ rằng đó là GStreamer ...

Các tài liệu cho các bindings python là cực kỳ nhẹ, và hầu hết có vẻ tập trung vào phiên bản cũ của phiên bản 0.10 của GStreamer thay vì các phiên bản 1.X mới, nhưng GStreamer là một nền tảng đa phương tiện cực kỳ mạnh mẽ có thể truyền, chuyển đổi, chuyển mã và hiển thị mọi thứ.

+0

tôi không còn cần điều này nữa, nhưng cảm ơn bạn anyway –

11

Trả lời: Không. Không có thư viện/giải pháp duy nhất trong python để ghi video/âm thanh cùng một lúc. Bạn phải triển khai cả hai cách riêng biệt và hợp nhất tín hiệu âm thanh và video theo cách thông minh để kết thúc bằng tệp video/âm thanh.

Tôi nhận được giải pháp cho sự cố bạn thể hiện. Mã của tôi giải quyết ba vấn đề của bạn:

  • Ghi lại video + âm thanh từ webcam và micrô cùng một lúc.
  • Nó lưu tệp video/âm thanh cuối cùng thành.AVI
  • Dòng không nhận xét 76, 77 và 78 sẽ làm cho video được hiển thị trên màn hình trong khi quay.

Giải pháp của tôi sử dụng pyaudio để ghi âm, opencv để quay video và ffmpeg để kết hợp hai tín hiệu. Để có thể ghi lại cả hai cùng một lúc, tôi sử dụng đa luồng. Một luồng ghi lại video và một đoạn âm thanh thứ hai. Tôi đã tải lên mã của tôi để github và cũng đã bao gồm tất cả các phần thiết yếu nó ở đây.

https://github.com/JRodrigoF/AVrecordeR

Lưu ý: opencv không có khả năng kiểm soát fps mà tại đó các webcamera hiện ghi hình. Nó chỉ có thể chỉ định trong bảng mã của tập tin fps cuối cùng mong muốn, nhưng webcamera thường hoạt động khác nhau theo thông số kỹ thuật và điều kiện ánh sáng (tôi tìm thấy). Vì vậy, khung hình/giây phải được kiểm soát ở cấp mã.

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

Bạn có biết điều này có thể được thực hiện để làm việc theo Python 3.x (lý tưởng 3.4) không? –

+0

làm thế nào để hỗ trợ mac os? – Gank

+0

Tôi không biết nếu các thư viện được sử dụng ở đây cũng có sẵn cho python 3. – JRodrigoF

Các vấn đề liên quan