2013-01-03 64 views
12

sto cercando una soluzione, sia in Linux o Windows, che mi permette diCome catturare un video (e audio) in python, da una fotocamera (o webcam)

  • registrare video (+ audio) dalla mia webcam & microfono, contemporaneamente.
  • salvarlo come file.avi (o mpg o qualsiasi altra cosa)
  • visualizzare il video sullo schermo durante la registrazione

compressione non è un problema nel mio caso, e io in realtà preferiscono catturare RAW e comprimerlo più tardi.

Finora l'ho fatto con un componente ActiveX in VB che si è occupato di tutto, e mi piacerebbe progredire con python (la soluzione VB è instabile, inaffidabile).

finora ho visto codice che cattura solo VIDEO, o singoli fotogrammi ...

Ho guardato finora a

  • OpenCV - non riusciva a trovare la cattura audio ci
  • PyGame: nessuna acquisizione audio simultanea (AFAIK)
  • VideoCapture: fornisce solo fotogrammi singoli.
  • simplecv - senza audio
  • VLC - VideoLAN legame al programma in wxPthon - spero che lo farà (ancora indagando questa opzione)
  • kivy - solo sentito parlare, non sono riuscito a farlo funzionare sotto le finestre SO LONTANO.

La domanda: c'è un video & libreria di acquisizione audio per python?

oppure - quali sono le altre opzioni se presenti?

risposta

2

Suggerirei ffmpeg. C'è un wrapper python.

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

+0

non ho visto come ffmpeg può essere utilizzato anche per visualizzare il video durante la registrazione. (ad esempio è possibile incorporare vlc in wxpython o come finestra senza bordi autonoma) –

1

Ho cercato in giro per una buona risposta a questo, e penso che sia GStreamer ...

La documentazione per i binding Python è estremamente leggero, e la maggior parte di esso sembrava centrato attorno alla vecchia versione 0.10 di GStreamer invece delle nuove versioni 1.X, ma GStreamer è un framework multimediale estremamente potente e multipiattaforma in grado di trasmettere, mux, transcodificare e visualizzare qualsiasi cosa.

+0

non ho più bisogno di questo, ma grazie comunque –

11

Risposta: No. Non esiste una singola libreria/soluzione in Python per eseguire contemporaneamente registrazioni video/audio. Devi implementare entrambi separatamente e unire il segnale audio e video in modo intelligente per finire con un file video/audio.

Ho una soluzione per il problema che presenti. Il mio codice risolve i tuoi tre problemi:

  • Registra video + audio da webcam e microfono contemporaneamente.
  • Salva il file video/audio finale come.AVI
  • Le righe senza commento 76, 77 e 78 renderanno il video da visualizzare sullo schermo durante la registrazione.

mia soluzione utilizza pyaudio per la registrazione audio, opencv per la registrazione video, e ffmpeg per muxing i due segnali. Per poter registrare entrambi contemporaneamente, utilizzo il multithreading. Un thread registra video e un secondo l'audio. Ho caricato il mio codice su github e ho incluso anche tutte le parti essenziali qui.

https://github.com/JRodrigoF/AVrecordeR

Nota: opencv non è in grado di controllare l'fps in cui il webcamera fa la registrazione. È solo in grado di specificare nella codifica del file gli fps finali desiderati, ma la webcam generalmente si comporta in modo diverso a seconda delle specifiche e delle condizioni di luce (ho trovato). Quindi i fps devono essere controllati a livello del codice.

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

Sai se questo può essere fatto funzionare con Python 3.x (idealmente 3.4)? –

+0

come supportare mac os? – Gank

+0

Non so se le librerie usate qui siano disponibili anche per python 3. – JRodrigoF

Problemi correlati