从Python进程播放MP3';通过omxplayer访问内存,无需写入磁盘
下面的代码接收MP3,将其写入磁盘并使用OMXPlayer播放。我想消除播放MP3之前将其写入磁盘的需要从Python进程播放MP3';通过omxplayer访问内存,无需写入磁盘,python,omxplayer,Python,Omxplayer,下面的代码接收MP3,将其写入磁盘并使用OMXPlayer播放。我想消除播放MP3之前将其写入磁盘的需要 song = response.content file = open("temp.mp3", "wb") file.write(song) file.close() response.close() play_song_subprocess = subprocess.call(['omxplayer', '-o', 'local', '--vol',
song = response.content
file = open("temp.mp3", "wb")
file.write(song)
file.close()
response.close()
play_song_subprocess = subprocess.call(['omxplayer', '-o', 'local', '--vol', '-500', 'temp.mp3'])
如何消除文件.write()
?
我想做这样的事情:
song = response.content
play_song_subprocess = subprocess.call(['omxplayer', '-o', 'local', '--vol', '-500', song])
但这会导致以下错误:
嵌入式空字节读者背景故事
在聊天和评论中建立:
导致SEG故障cat temp.mp3 | omxplayer-o local--vol-500/dev/stdin
;如果从omxplayer-o local--vol-500/dev/fd/3
cat file.mp3 | omxplayer-o local--vol-500/dev/stdin
中读取内容有效,那么我们应该能够编写同样有效的Python。(该测试的原因是FIFO是不可查找的:它只能从开始到结束读取一次;不能向前跳、向后退等;并非所有用于操作媒体文件的软件都可以这样操作——有时他们希望能够多次读取内容,或者向前跳到页脚,等等)。(顺便说一句,只是为了解释“嵌入的空字节”错误--命令行由C字符串列表组成。C字符串由它们包含的第一个NUL终止;因此,您不能将包含任何NUL的数据放入命令行参数中。并且无论如何--/dev/stdin
希望该位置的任何内容都是文件名,而不是要播放的数据;如果它试图打开您的data就好像它是一个文件名一样,您可能会在以后遇到另一个错误。)@CharlesDuffy感谢您的评论,但是subprocess.call()并不总是需要文件系统操作。例如:subprocess.call(['omxplayer','-o','local','--vol','-500',')很好。是的,我知道你的意思。这就是为什么我告诉你用omxplayer
运行测试的原因(我正焦急地等待对该测试的回应)。但问题的关键是,最初的问题标题要求的是一些从迂腐的意义上说不可能的东西,因此,更清晰的标题会改善情况。/dev/stdin
import tempfile, os, os.path, shutil, subprocess fifo_dir = None try: fifo_dir = tempfile.mkdtemp('mp3-fifodir') fifo_name = os.path.join(fifo_dir, 'fifo.mp3') os.mkfifo(fifo_name) # now, we start omxplayer, and tell it to read from the FIFO # as long as it opens it in read mode, it should just hang until something opens # ...the write side of the FIFO, writes content to it, and then closes it. p = subprocess.Popen(['omxplayer', '-o', 'local', '--vol', '-500', fifo_name]) # this doesn't actually write content to a file on disk! instead, it's written directly # ...to the omxplayer process's handle on the other side of the FIFO. fifo_fd = open(fifo_name, 'w') fifo_fd.write(song) fifo_fd.close() p.wait() finally: shutil.rmtree(fifo_dir)
import os, subprocess def move_stdin(): os.dup2(0, 3) # copy our stdin -- FD 0 -- to FD 3 try: newstdin = open('/dev/tty', 'r') # open /dev/tty... os.dup2(newstdin.fileno(), 0) # ...and attach it to FD 0. except IOError: newstdin = open('/dev/null', 'r') # Couldn't do that? Open /dev/null... os.dup2(newstdin.fileno(), 0) # ...and attach it to FD 0. p = subprocess.Popen(['omxplayer', '-o', 'local', '--vol', '-500', '/dev/fd/3'], stdin=subprocess.PIPE, preexec_fn=move_stdin, pass_fds=[0,1,2,3]) p.communicate(song)