Сохранение потока во время воспроизведения с использованием 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, Согласно этот doc, команда для сохранения потока:

--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 ++.


Я создал похожий, но не дубликат, тема вчера.

19

Решение

Идея:

Основная идея достаточно проста. Вы должны продублировать поток вывода и перенаправить его в файл. Это сделано, как Maresh правильно указано, используя Sout = # дубликат {…} директивы.

Рабочее решение:

Следующее решение работает на моей машине ™. Я протестировал его на 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

Полезные ссылки


Приведенный выше код не очень подходит для 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 — это битрейт видео в кбит / с.
  • ab = 128 — битрейт аудио в кбит / с.
  • 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 в директиве transcode. Кажется, важно использовать соответствующие расширения для выходного файла (в данном случае mpg). В противном случае VLC запутывается при открытии сохраненного файла для воспроизведения. Имейте это в виду, если вы решите переключиться на другой формат видео.

Вы не можете добавить обычный URL-адрес YouTube в качестве пути к файлу. Вместо этого вы должны указать местоположение самого видео. Вот почему путь к файлу, который я использовал, выглядит так загадочно. Этот путь к файлу соответствует видео в http://www.youtube.com/watch?v=GQe3JxJHpxQ, Сам VLC может извлечь местоположение видео из заданного URL-адреса YouTube, но libVLC не делает этого «из коробки». Вам придется написать свой собственный распознаватель, чтобы сделать это. Смотрите этот связанный вопрос так. я следовал этому подходу вручную разрешить местоположение видео для моих тестов.

8

Другие решения

Я думаю, что вам нужно дублировать вывод, чтобы воспроизвести и записать его одновременно:

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}}")
5

Вы пытались добавить в список опций следующую опцию?

—Sout-дисплей

то есть

instance = vlc.Instance("--sub-source marq --sout=file/ps:example.mpg --sout-display")
1

Некоторое время назад в примере кода на веб-сайте активного состояния я видел, как кто-то воспроизводил и записывал файл MP3 с использованием VLC с помощью модуля vlc.py. Вы можете взглянуть на его пример кода, чтобы увидеть, как дублировать поток. Я скопировал этот код для вас (я скопировал его из 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" WAVE\n' %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 AUDIO\n' %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 %s\n' %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()
1

Возможно, вам нужно клонировать свой вывод, как предложено на форуме?

0
По вопросам рекламы [email protected]