使用LibVLC在播放时保存流
Saving a stream while playing it using LibVLC
使用LibVLC,我试图在播放时保存流。这是python代码:
import os
import sys
import vlc
if __name__ == '__main__':
filepath = <either-some-url-or-local-path>
movie = os.path.expanduser(filepath)
if 'http://' not in filepath:
if not os.access(movie, os.R_OK):
print ( 'Error: %s file is not readable' % movie )
sys.exit(1)
instance = vlc.Instance("--sub-source marq --sout=file/ps:example.mpg")
try:
media = instance.media_new(movie)
except NameError:
print ('NameError: % (%s vs Libvlc %s)' % (sys.exc_info()[1],
vlc.__version__, vlc.libvlc_get_version()))
sys.exit(1)
player = instance.media_player_new()
player.set_media(media)
player.play()
#dont exit!
while(1):
continue
将视频流保存到文件example.mpg
。根据本文档,保存流的命令如下:
--sout=file/ps:example.mpg
,我在创建vlc.Instance
的实例时使用:
instance = vlc.Instance("--sub-source marq --sout=file/ps:example.mpg")
但是问题是只有保存流,它不能同时播放流。
是否有任何方法(在LibVLC)我可以保存流(到本地文件),而支付它?
虽然,我正在寻找Python 3.3.1
的解决方案,但如果有任何C或c++解决方案,那就好了。
我昨天已经创建了一个类似但不重复的主题
创意:
基本思想很简单。您必须复制输出流并将其重定向到一个文件。正如Maresh正确指出的那样,使用sout=#duplicate{…} 指令。
工作方案:
下面的解决方案适用于我的机器™。我在Ubuntu 12.10、VLC v2.0.3 (TwoFlower)和Python 2.7.1上测试了它。我认为它也可以在Python 3上工作,因为大多数繁重的工作都是由libVlc完成的。
import os
import sys
import vlc
if __name__ == '__main__':
#filepath = <either-some-url-or-local-path>
movie = os.path.expanduser(filepath)
if 'http://' not in filepath:
if not os.access(movie, os.R_OK):
print ( 'Error: %s file is not readable' % movie )
sys.exit(1)
instance = vlc.Instance("--sout=#duplicate{dst=file{dst=example.mpg},dst=display}")
try:
media = instance.media_new(movie)
except NameError:
print ('NameError: % (%s vs Libvlc %s)' % (sys.exc_info()[1],
vlc.__version__, vlc.libvlc_get_version()))
sys.exit(1)
player = instance.media_player_new()
player.set_media(media)
player.play()
#dont exit!
while(1):
continue
- 命令行帮助对于破译过多的vlc是必不可少的命令行选项
- VLC流媒体规范第三章。解释流输出的结构、它的指令和各种可用模块的描述。第4章给出了一些例子。
- LibVLC API文档,如果你想改变媒体选项在运行时
更新-保存YouTube视频:
上面的代码不能很好地在YouTube上运行。我搜索了一下,发现一个额外的transcode
指令可以用来将YouTube的视频流转换为常规的视频格式。我使用#transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128,deinterlace}
- vcodec=mp4v是您想要编码的视频格式(mp4v是MPEG-4, mpgv是MPEG-1,还有h263, DIV1, DIV2, DIV3, I420, I422, I444, RV24, YUY2)。
- acodec=mpga是你想要编码的音频格式(mpga是MPEG音频第2层,a52是a52即AC3声音)。
- vb=800为视频比特率,单位为Kbit/s。
- ab=128为音频比特率,单位为Kbit/s。
- deinterlace告诉VLC在飞行中去交错视频。
更新后的代码如下所示:
import os
import sys
import vlc
if __name__ == '__main__':
#filepath = <either-some-url-or-local-path>
filepath = "http://r1---sn-nfpnnjvh-1gil.c.youtube.com/videoplayback?source=youtube&newshard=yes&fexp=936100%2C906397%2C928201%2C929117%2C929123%2C929121%2C929915%2C929906%2C929907%2C929125%2C929127%2C925714%2C929917%2C929919%2C912512%2C912515%2C912521%2C906838%2C904485%2C906840%2C931913%2C904830%2C919373%2C933701%2C904122%2C932216%2C936303%2C909421%2C912711%2C907228%2C935000&sver=3&expire=1373237257&mt=1373214031&mv=m&ratebypass=yes&id=1907b7271247a714&ms=au&ipbits=48&sparams=cp%2Cid%2Cip%2Cipbits%2Citag%2Cratebypass%2Csource%2Cupn%2Cexpire&itag=45&key=yt1&ip=2a02%3A120b%3Ac3c6%3A7190%3A6823%3Af2d%3A732c%3A3577&upn=z3zzcrvPC0U&cp=U0hWSFJOVV9KUUNONl9KSFlDOmt4Y3dEWFo3dDFu&signature=D6049FD7CD5FBD2CC6CD4D60411EE492AA0E9A77.5D0562CCF4E10A6CC53B62AAFFF6CB3BB0BA91C0"
movie = os.path.expanduser(filepath)
savedcopy = "yt-stream.mpg"
if 'http://' not in filepath:
if not os.access(movie, os.R_OK):
print ( 'Error: %s file is not readable' % movie )
sys.exit(1)
instance = vlc.Instance("--sout=#transcode{vcodec=mp4v,acodec=mpga,vb=800,ab=128,deinterlace}:duplicate{dst=file{dst=%s},dst=display}" % savedcopy)
try:
media = instance.media_new(movie)
except NameError:
print ('NameError: % (%s vs Libvlc %s)' % (sys.exc_info()[1],
vlc.__version__, vlc.libvlc_get_version()))
sys.exit(1)
player = instance.media_player_new()
player.set_media(media)
player.play()
#dont exit!
while(1):
continue
几个要点:
我在转码指令中使用了MPEG音频和视频编解码器。对输出文件使用匹配的扩展名(在本例中为mpg)似乎很重要。否则VLC在打开保存的文件进行播放时会感到困惑。如果你决定切换到另一种视频格式,请记住这一点。
不能添加普通的YouTube URL作为文件路径。相反,您必须指定视频本身的位置。这就是为什么我使用的文件路径看起来如此神秘的原因。该文件路径对应于http://www.youtube.com/watch?v=GQe3JxJHpxQ
的视频。VLC本身能够从给定的YouTube URL中提取视频位置,但libVLC并没有这样做。您必须编写自己的解析器来实现这一点。请看这个相关的SO问题。我遵循此方法手动解析测试的视频位置。
我认为你需要复制输出,以便同时播放和录制它:
vlc.Instance("--sub-source marq --sout=#stream_out_duplicate{dst=display,dst=std{access=file,mux=ts,dst=/path/file.mpg}}")
或
libvlc_media_add_option(media, ":sout=#stream_out_duplicate{dst=display,dst=std{access=file,mux=ts,dst=/path/file.mpg}}")
您是否尝试将以下选项添加到选项列表中?
——sout-display
。
instance = vlc.Instance("--sub-source marq --sout=file/ps:example.mpg --sout-display")
前段时间在活动状态网站的示例代码中,我看到有人使用VLC使用VLC .py模块播放和录制MP3文件。您可以查看示例代码,了解如何复制流。我为你复制了这里的代码(我从http://code.activestate.com/recipes/577802-using-vlcpy-to-record-an-mp3-and-save-a-cue-file/):
复制的)import vlc
import time
import os
def new_filename(ext = '.mp3'):
"find a free filename in 00000000..99999999"
D = set(x[:8] for x in os.listdir('.')
if (x.endswith(ext) or x.endswith('.cue')) and len(x) == 12)
for i in xrange(10**8):
s = "%08i" %i
if s not in D:
return s
def initialize_cue_file(name,instream,audiofile):
"create a cue file and write some data, then return it"
cueout = '%s.cue' %name
outf = file(cueout,'w')
outf.write('PERFORMER "%s"n' %instream)
outf.write('TITLE "%s"n' %name)
outf.write('FILE "%s" WAVEn' %audiofile)
outf.flush()
return outf
def initialize_player(instream, audiofile):
"initialize a vlc player which plays locally and saves to an mp3file"
inst = vlc.Instance()
p = inst.media_player_new()
cmd1 = "sout=#duplicate{dst=file{dst=%s},dst=display}" %audiofile
cmd2 ="no-sout-rtp-sap"
cmd3 = "no-sout-standard-sap"
cmd4 ="sout-keep"
med=inst.media_new(instream,cmd1,cmd2,cmd3,cmd4)
med.get_mrl()
p.set_media(med)
return p, med
def write_track_meta_to_cuefile(outf,instream,idx,meta,millisecs):
"write the next track info to the cue file"
outf.write(' TRACK %02i AUDIOn' %idx)
outf.write(' TITLE "%s"n' %meta)
outf.write(' PERFORMER "%s"n' %instream)
m = millisecs // 60000
s = (millisecs - (m*60000)) // 1000
hs = (millisecs - (m*60000) - (s*1000)) //10
ts = '%02i:%02i:%02i' %(m,s,hs)
outf.write(' INDEX 01 %sn' %ts)
outf.flush()
def test():
#some online audio stream for which this currently works ....
instream = 'http://streamer-mtc-aa05.somafm.com:80/stream/1018'
#if the output filename ends with mp3 vlc knows which mux to use
ext = '.mp3'
name = new_filename(ext)
audiofile = '%s%s' %(name,ext)
outf = initialize_cue_file(name,instream,audiofile)
p,med = initialize_player(instream, audiofile)
p.play()
np = None
i = 0
while 1:
time.sleep(.1)
new = med.get_meta(12)
if new != np:
i +=1
t = p.get_time()
print "millisecs: %i" %t
write_track_meta_to_cuefile(outf,instream,i,new,t)
np = new
print "now playing: %s" %np
if __name__=='__main__':
test()
也许您需要像论坛上建议的那样克隆您的输出?
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- SFML纹理像播放器
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- EvtExportLogneneneba API正在将远程计算机的事件日志保存到远程PC本身.如何将其保存到主机
- 在C++中将类(带有Vector成员)保存为二进制文件
- C++.我想将更改后的特定字符行保存在字符串中
- 使用FFMPEG将RGB图像序列保存到.mp4时出现问题
- 将RGB图像保存为PPM格式
- 哈希文件递归并保存到矢量Cryptopp中
- 如何将二进制格式的 C++ 对象的 std::vector 保存到磁盘?
- 无法通过头文件保存变量的值
- 根据用户回答声明"Players"。用户选择玩家数量。播放器是结构体
- 如何收听Windows当前正在播放的声音?
- 我们可以将数据永久保存为数据结构吗?
- Qt C++ 创建方形音频音调波.播放并保存它
- 使用LibVLC在播放时保存流