2012-05-01 17 views
6

Tôi đang cố gắng sử dụng ffmpeg với mô-đun phụ của Python để chuyển đổi một số tệp âm thanh. Tôi lấy các tập tin âm thanh từ một URL và muốn chỉ có thể vượt qua các đối tượng tập tin Python để ffmpeg, thay vì đầu tiên lưu chúng vào đĩa. Nó cũng sẽ rất tốt đẹp nếu tôi chỉ có thể lấy lại một dòng tập tin thay vì có ffmpeg lưu đầu ra vào một tập tin.Làm cách nào để sử dụng ffmpeg với Python bằng cách chuyển đối tượng tệp (thay vì vị trí vào tệp trên đĩa)

Để tham khảo, đây là những gì tôi đang làm bây giờ:

tmp = "/dev/shm" 
audio_wav_file = requests.get(audio_url) 
##    ##       ## 
## This is what I don't want to have to do ## 
wavfile = open(tmp+filename, 'wrb') 
wavfile.write(audio_wav_file.content) 
wavfile.close() 
##    ##       ## 
conversion = subprocess.Popen('ffmpeg -i "'+tmp+filename+'" -y "'+tmp+filename_noext+'.flac" 2>&1', shell = True, stdout = subprocess.PIPE).stdout.read() 

Có ai biết làm thế nào để làm điều này?

Cảm ơn!

Trả lời

7

với ffmpeg bạn có thể sử dụng - làm tên tệp đầu vào/đầu ra để cho biết rằng nó sẽ đọc dữ liệu từ stdin/write to stdout.

Sau đó, bạn có thể sử dụng các đối số stdin/stdout của Popen để đọc/ghi dữ liệu của mình.

một ví dụ:

from subprocess import Popen, PIPE 

with open("test.avi", "rb") as infile: 
    p=Popen(["ffmpeg", "-i", "-", "-f", "matroska", "-vcodec", "mpeg4", 
     "-acodec", "aac", "-strict", "experimental", "-"], 
      stdin=infile, stdout=PIPE) 
    while True: 
     data = p.stdout.read(1024) 
     if len(data) == 0: 
      break 
     # do something with data... 
     print(data) 
    print p.wait() # should have finisted anyway 

thay vào đó bạn cung cấp một tập tin cho stdin bạn cũng có thể sử dụng một PIPE và ghi trực tiếp vào dòng quá trình đầu vào (p.stdin). hoặc trong trường hợp của bạn, bạn chỉ cần sử dụng wavfile ...

lưu ý rằng bạn phải chỉ định định dạng đầu ra và codec rõ ràng, vì ffmpeg không thể đoán chúng từ phần mở rộng tệp như thường lệ.
và nó sẽ chỉ hoạt động cho các bộ chuyển đổi không cần luồng đầu ra có thể tìm kiếm, nhưng flac sẽ hoạt động ...

0

Kể từ khi nó trông giống như bạn đang ở trên Unix (không .exe vào cuối 'ffmpeg'), tôi sẽ khuyên bạn nên sử dụng một ống tên, aka fifo:

mkfifo multimedia-pipe 

Có kịch bản Python viết dữ liệu âm thanh thành 'tệp đa phương tiện' và yêu cầu FFmpeg đọc từ cùng một tệp. Tôi đã sử dụng mẫu này để giải mã các tệp đa phương tiện vào các đại diện thô, thô của chúng để xác thực mà không phải chiếm dung lượng đĩa.

Hoặc, hãy thử chuyển URL 'http: // ...' trực tiếp đến tùy chọn nhập của FFmpeg.