Audio/video stream recording forums
|
Attention Visitor: |
You may have to register or log in before you can post:
|
|
|
Thread Tools | Display Modes |
#1
|
|||
|
|||
librtmp and pythonHi everybody,
since a few days I'm facing a very stressful issue with librtmp and python 2.7 (my os is Windows 7). I'm trying to connect to a stream on justin tv but I've probably an encoding issue with jtv token string. Here is my code: Code:
print 'instantiate rtmp connection' r = dll.RTMP_Alloc() dll.RTMP_Init(r) dll.RTMP_SetupURL(r, c_char_p(tcUrl)) print 'connect to stream' dll.RTMP_Connect(r, None) print 'read stream' dll.RTMP_Read(r) tcUrl=rtmp://199.9.255.143/app/jtv_toTs9DzRvV8WPazW swfUrl=http://www-cdn.jtvnw.net/widgets/live_site_player.ra3170e7f148ff63b2f1b4dfef2840842 de54e7f8 .swf token=a6faa3f74e0927e80039bb612522d637530d6395:{\" swfDomains\": [\"justin.tv\", \"jtvx.com\", \"xarth.com\", \"twitchtv.com\", \"twitch.tv\", \"n ewjtv.com\", \"jtvnw.net\", \"wdtinc.com\", \"imapweather.com\", \"facebook.com\", \"starcrafting.com\"], \"streamName\": \"jtv_toTs9DzRvV8WPazW\", \" expiration\": 1332084704.643841, \"geo_ip\": \"82.243.172.91\", \"server\": \"lhr01-video3-2\"} does anybody knows how to fix this? Thanks Regards, Gontran |
#2
|
|||
|
|||
Re: librtmp and pythonQuote:
Code:
Special characters in values may need to be escaped to prevent misinterpretation by the option parser. The escape encoding uses a backslash followed by two hexadecimal digits representing the ASCII value of the character. E.g., spaces must be escaped as \20 and backslashes must be escaped as \5c. Code:
jtv=a6faa3f74e0927e80039bb612522d637530d6395:{\22\20swfDomains\22:\20[\22justin.tv\22,\20\22jtvx.com\22,\20\22xarth.com\22,\20\22twitchtv.com\22,\20\22twitch.tv\22,\20\22newjtv.com\22,\20\22jtvnw.net\22,\20\22wdtinc.com\22,\20\22imapweather.com\22,\20\22facebook.com\22,\20\22starcrafting.com\22],\20\22streamName\22:\20\22jtv_toTs9DzRvV8WPazW\22,\20\22expiration\22:\201332084704.643841,\20\22geo_ip\22:\20\2282.243.172.91\22,\20\22server\22:\20\22lhr01-video3-2\22} |
#3
|
|||
|
|||
Re: librtmp and pythonThank you KSV, you made my day.
Though I read the doc, I dont understand how I missed that! |
#4
|
|||
|
|||
Re: librtmp and pythonNow that I managed to retrieve a stream, I would like to get log from librtmp.
According to ctypes documentation and given functions signatures from log.h/log.c, I wrote this in my code: Code:
CMPFUNC = CFUNCTYPE(c_int, c_int, c_char_p, c_void_p) def logCallBack(level, message, va_list): dll.RTMP_LogPrintf(message, va_list) return 0 mLogCallBack = CMPFUNC(logCallBack) ... dll.RTMP_LogSetCallback(mLogCallBack) Code:
Parsed host : ☺Parsed app : ☺connect to stream ÄßGj♫¨', ... connected, handshaking?ßGj♥: Type Answer : 27DBEC?ßGjä?┼♣: Server Uptime : 2612204?ßGj♥: FMS Version : 2612204.2612100.488283845.4882 83530?ßGj♥: Handshaking finished....ÄßGj♫¨', handshaked│°Gj♀☻: fd=2614284, size=2614180Invoking ▒?'ä°Gj♀☻: fd=2618556`÷Gjá%&: server BW = 2618572ä°Gj♀ ☻: fd=2618556o÷Gjá%&: client BW = 2618572 2618468ä°Gj♀☻: fd=2618556?÷Gj, received ctrl. type: 2618572, len: 2618468?÷Gj, Stream Begin 2618572ä°Gj♀☻: f d=26185568÷Gj, received: chunk size change to 2618572ä°Gj♀☻: fd=2618556N÷Gj♣☺, received: invoke 2618572 bytes(object begin)Property: <|±'☺>Property: < |±'☺>Property: <|±'OBJECT>(object begin)Property: <,´'☺>Property: <,´'☺>Property: <,´'☺>(object end)Property: <|±'OBJECT>(object begin)Property: <,´'☺ >Property: <,´'☺>Property: <,´'☺>Property: <,´'OBJECT>(object begin)Property: <▄ý'☺>(object end)Property: <,´'☺>Property: <,´'☺>(object end)(object en d)~÷Gjmt;, server invoking <☺>~÷Gj, received result for method call <☺>│°Gj♀☻: fd=2616844, size=2616740sending ctrl. type: 0x27f264│°Gj♀☻: fd=2616828, size=2616724│°Gj♀☻: fd=2616828, size=2616724Invoking ?‗'UsherToken: ú?B☻,☺│°Gj♀☻: fd=2617164, size=2617060Invoking )¶'ä°Gj♀☻: fd=2618556N÷Gj↔, receiv ed: invoke 2618572 bytes(object begin)Property: <|±'☺>Property: <|±'☺>Property: NULLProperty: <|±'☺>(object end)~÷Gj?⌂;, server invoking <☺>~÷Gj8¶;, r eceived result for method call <☺>¶÷Gj, seekTime=2617308, stopTime=2617204, sending play: â─↑?♥â╚*?e¶╔├U?ýâý►SVW?¨?w►?E*ëE??F♦┴Ó☻?┌??↨│°Gj♀☻: fd=26171 64, size=2617060Invoking )¶'sending ctrl. type: 0x27f264│°Gj♀☻: fd=2616828, size=2616724ä°Gj♀☻: fd=2618556N÷Gj%, received: invoke 2618572 bytes(object begin)Property: <|±'☺>Property: <|±'☺>Property: NULLProperty: <|±'☺>(object end)~÷Gj?⌂;, server invoking <☺>~÷Gj, received result id 2617308 without matching requestä°Gj♀☻: fd=2618556?÷Gj, received ctrl. type: 2618572, len: 2618468?÷Gj☺, Stream Begin 2618572ä°Gj♀☻: fd=2618556N÷Gjö, received: invoke 2618572 bytes(object begin)Property: <|±'☺>Property: <|±'☺>Property: NULLProperty: <|±'OBJECT>(object begin)Property: <,´'☺>Property: <,´'☺>Property: <,´'☺>Property: <,´'☺>(object end)(object end)~÷Gj?t;, server invoking <☺>~÷Gj┴t;, onStatus: ☺ä°Gj♀☻: fd=2618556N÷Gj?, received: invoke 2618572 bytes (object begin)Property: <|±'☺>Property: <|±'☺>Property: NULLProperty: <|±'OBJECT>(object begin)Property: <,´'☺>Property: <,´'☺>Property: <,´'☺>Propert y: <,´'☺>Property: <,´'☺>Property: <,´'☺>(object end)(object end)~÷Gj?t;, server invoking <☺>~÷Gj┴t;, onStatus: ☺read stream ä°Gj♀☻: fd=2618348N÷Gj,, received: notify 2618364 bytes(object begin)Property: <(§'☺>Property: <(§'OBJECT>(object begin)Property: <?‗'☺>(object end)(o bject end)ä°Gj♀☻: fd=2618348ä°Gj♀☻: fd=2618348N÷Gj?♥, received: notify 2618364 bytes(object begin)Property: <(§'☺>Property: <(§'OBJECT>(object begin)P roperty: <?‗'☺>Property: <?‗'☺>Property: <?‗'☺>Property: <?‗'☺>Property: <?‗'☺>Property: <?‗'☺>Property: <?‗'☺>Property: <?‗'☺>Property: <?‗'☺>Propert y: <?‗'☺>Property: <?‗'☺>Property: <?‗'OBJECT>(object begin)Property: <?*'OBJECT>(object begin)Property: <8?'☺>Property: <8?'☺>Property: <8?'OBJECT>(o bject begin)Property: <??'OBJECT>(object begin)Property: <?Ú'☺>(object end)(object end)Property: <8?'☺>(object end)Property: <?*'OBJECT>(object begin) Property: <8?'☺>Property: <8?'☺>Property: <8?'OBJECT>(object begin)Property: <??'OBJECT>(object begin)Property: <?Ú'☺>(object end)(object end)Property : <8?'☺>Property: <8?'☺>Property: <8?'☺>Property: <8?'☺>(object end)(object end)Property: <?‗'OBJECT>(object begin)Property: <?*'☺>Property: <?*'☺>Pro perty: <?*'☺>Property: <?*'☺>Property: <?*'☺>Property: <?*'☺>Property: <?*'OBJECT>(object begin)Property: <8?'☺>Property: <8?'☺>Property: <8?'☺>(objec t end)(object end)(object end)(object end)Metadata: ☺ ,±' ☺ ,±' ☺ ,±' ☺ ,±' ☺ ,±' ☺ ,±' ☺ ,±' ☺ ,±' ☺ ,±' ☺ ,±' ☺ ,±'☺: ☺ î?' ☺ î?'☺: ☺ ý?' ☺ î?' ☺ î?' ☺ î?'☺: ☺ ý?' ☺ î?' ☺ î?' ☺ î?' ☺ î?'☺: ☺ ▄´' ☺ ▄´' ☺ ▄´' ☺ ▄´' ☺ ▄´' ☺ ▄´'☺: ☺ î?' ☺ î?' ☺ î?'ä° Gj♀☻: fd=2618348│°Gj♀☻: fd=2618172, size=2618068Invoking ı¸' Code:
%s, ... connected, handshaking %s: Type Answer : %02X %s: Server Uptime : %d %s: FMS Version : %d.%d.%d.%d %s: Handshaking finished.... %s, handshaked %s: fd=%d, size=%d Invoking %s %s: fd=%d %s: server BW = %d %s: fd=%d %s: client BW = %d %d %s: fd=%d %s, received ctrl. type: %d, len: %d ... That 's why I'm asking for help. Thanks in advance. Regards, Gontran Last edited by Gontran : 03-20-2012 at 05:42 AM. |
#5
|
|||
|
|||
Re: librtmp and pythonI am not a python coder so i can't provide you a definite answer. but what you are referring as message in your code is actually format string. va_list contains the actual data to be filled in format string to create complete string. you can't pass va_list to another function. try to use PyArg_VaParse.
|
#6
|
|||
|
|||
Re: librtmp and pythonThank you KSV for your concern but as far as I know, PyArg_VaParse has to be used in c programms.
I tried to reproduce the same code as shown in this thread (http://stream-recorder.com/forum/usi...n-t11025.html? but this doesn't work. Anyway, I'll dig deeper tonight. Regards, Gontran |
#7
|
|||
|
|||
Re: librtmp and pythonJust don't pay attention to my last messages: I was tired and doing all wrong!
The only thing needed was to set the log level (by default nothing) in order to see logs in the standard output: Code:
#That's all!!!! dll.RTMP_LogSetLevel(c_int(6)) |
#8
|
|||
|
|||
Re: librtmp and pythonAs I said earlier, here a little class that wraps librtmp in order to get streams:
Code:
# -*- coding: utf-8 -*- import os from ctypes import cdll, c_char_p, c_int, create_string_buffer, sizeof class RTMP: """ This class encapsulates librtmp.dll in order to connect to a RTMP server and get video stream. RTMPDUMP website : http://rtmpdump.mplayerhq.hu LIBRTMP manpage : http://rtmpdump.mplayerhq.hu/librtmp.3.html """ LogLevel = { "RTMP_LOGCRIT" : c_int(0), "RTMP_LOGERROR" : c_int(1), "RTMP_LOGWARNING" : c_int(2), "RTMP_LOGINFO" : c_int(3), "RTMP_LOGDEBUG" : c_int(4), "RTMP_LOGDEBUG2" : c_int(5), "RTMP_LOGALL" : c_int(6) } def __init__(self, tcURL, output_file_path, log_level=LogLevel["RTMP_LOGINFO"], buffer_size=64 * 1024): # Load library if os.name == 'nt': self.lib = cdll.LoadLibrary('lib/librtmp.dll') elif os.name == 'posix': # TODO: load library for posix os pass # Initialize variables self.tcURL = tcURL self.output_file_path = output_file_path self.log_level = log_level self.buffer_size = buffer_size #************************************************************************ # Wrap native library functions def Alloc(self): """Return a pointer to a new RTMP object""" return self.lib.RTMP_Alloc() def Init(self, r_pointer): """Init the RTMP object""" self.lib.RTMP_Init(r_pointer) return None def SetupURL(self, r_pointer, tcURL): """ Setup the rtmp url The rtmp url format is of the form rtmp[t][e|s]://hostname[:port][/app[/playpath]] """ self.lib.RTMP_SetupURL(r_pointer, c_char_p(tcURL)) return None def Connect(self, r_pointer): """Established network connection""" self.lib.RTMP_Connect(r_pointer, None) return None def ConnectStream(self, r_pointer): """Established RTMP session""" self.lib.RTMP_ConnectStream(r_pointer, 0) return None def Read(self, r_pointer, buffer): """ Reads bytes from the stream an write its into the buffer. Returns the number of bytes read When it returns 0 bytes, the stream is complete and may be closed """ return self.lib.RTMP_Read(r_pointer, buffer, sizeof(buffer)) def Close(self, r_pointer): """ Closes the connection """ self.lib.RTMP_Close(r_pointer) return None def Free(self, r_pointer): """ Frees the session """ self.lib.RTMP_Free(r_pointer) return None def LogSetLevel(self, log_level): """ Defines RTMP_LogLevel used by output """ self.lib.RTMP_LogSetLevel(log_level) return None #************************************************************************ def getVideoStream(self): """ Get the video stream from the rtmp server """ # Try to open the output file try: output_file = open(self.output_file_path, 'wb') except: print "Cannot open output file.\n Please check the output_file_path\n. Aborting." return None # Instantiate buffer buffer = create_string_buffer(self.buffer_size) # Set LogLevel self.LogSetLevel(self.log_level) # Setup RTMP connection r_pointer = self.Alloc() self.Init(r_pointer) self.SetupURL(r_pointer, self.tcURL) # Connect and establish session self.Connect(r_pointer) self.ConnectStream(r_pointer) # Read stream try: while True: # While result > 0, write buffer bytes into output_file result = self.Read(r_pointer, buffer) output_file.write(buffer[:result]) if result == 0: break except: # Handles exception in order to close session and file properly print "An exception occured. Ending session." # Ends session and closes output_file self.Close(r_pointer) self.Free(r_pointer) output_file.close() Code:
# construct the url before as mentionned in librtmp manpage m_rtmp = RTMP(tcUrl, 'out_file.flv') m_rtmp.getVideoStream() Hope this will be usefull! Regards, Gontran |
#9
|
|||
|
|||
Re: librtmp and pythonQuote:
I started work on something similar about a month ago and I'm surpirsed your script works. I had to define custom ctype structure & union classes for my script, other wise it would complain about segmentation faults. I am running linux though, so maybe windows doesn't care as much. |
#10
|
|||
|
|||
Re: librtmp and pythongontran,i see your ip on 1 post or not?
|
Tags: librtmp, python |
Thread Tools | |
Display Modes | |
|
|