GNOME Bugzilla – Bug 566604
Add RTMP client support
Last modified: 2013-11-30 16:43:12 UTC
As used by Flash: http://en.wikipedia.org/wiki/Real_Time_Messaging_Protocol and: http://xbmc.org/trac/ticket/4905
Example of how Swedish Television RTMP stuff is played in Xbox Media Center: item = xbmcgui.ListItem("svt video") item.setProperty("SWFPlayer", "http://svt.se/svt/road/Classic/shared/flash/VideoPlayer/svtplayer.swf") item.setProperty("PlayPath", "kluster/20081228/0812292020_GJKLS332") xbmc.Player(xbmc.PLAYER_CORE_DVDPLAYER).play("rtmp://fl1.c00928.cdn.qbrick.com/00928/_definst_/kluster/20081228/0812292020_GJKLS332", item) In this case the PlayPath can be extracted from the url, not sure if that could be done automagically, however, the SWFPlayer url needs to be passed along with it.
See also: http://sourceforge.net/projects/rtmpdump/ Which has some code to stream the media.
http://github.com/elan/plex/tree/7ef4e0801fec6a1199ba6f6c9294ba6e565aa10d/xbmc/lib/libRTMP http://xbmc.org/trac/browser/trunk/XBMC/xbmc/lib/libRTMP The one from Plex and XBMC *should* be very much identical. They both origin from Boxee, but I can't find Boxee's public repository so those two above will have to serve as an example for now.
Speak of the devil... http://www.fosdem.org/2009/schedule/events/reverse_engineering
Created attachment 148471 [details] [review] patch against flvstreamer This is a patch against flvstreamer SVN trunk. Run "make gstreamer-install" on a clean tree and you should see a "rtmpsrc" in gst-inspect. This doesn't work yet because: - WriteStream() should be in the RTMP object, so we don't have to know all that horror - There's no public functions to allow seeking - There's no way to get the size in bytes - There's no way to detect whether a stream is live or not Finally, there's a bunch of FIXMEs, and we should trim the options list so that passing a location and swfurl would be enough for most streams. Once flvstreamer is LGPL[1], we could add this in -bad. [1] https://savannah.nongnu.org/support/?106992
So, here's an overview about my thoughts about RTMP. RTMP is a protocol that allows you to send basically 3 types of streams: 1) video data 2) audio data 3) remote procedure calls It is easy to interpret 1) and 2) - in fact, an FLV file is pretty much just a dump of the server=>client part of an RTMP session. The problem is the remote calls. The remote calls are used to execute functions inside the Flash Player. These functions get defined inside the SWF file that opens the RTMP connection and are executed in one of the many virtual machines of the Flash player in the context of the Flash DOM. So to handle RTMP 100%, you must run a working Flash player and have the launching SWF file at hand. From this point of view, it makes absolutely no sense to try to add RTMP support to GStreamer separate from a full Flash player. And no, the current Gnash or Swfdec implementations do not count. However, quite a few Flash sites I've come across do use the default components of Adobe's Flash Media Server. That software ships a bunch of components that implement video streaming and live broadcasts and they are quite complex. So it is no wonder that people prefer to just drop them into their server and use them as is. So what the Open Source RTMP tools do is implement compatibility to these components - of course the components come in multiple versions and with quite a few configuration options. They try to implement the default responses to all the remote functions calls. They do not attempt to interpret or even download the code of the functions that should be called. So this is a very huge hack that fails whenever a site uses custom Flash code or a new version of the components gets released. But it often works quite well. In summary, I have no idea if it is a worthwhile goal to pursue such a project. Before judging that I would like to have the biggest 50 RTMP using sites audited for the way their servers work. And I've never tried that. I just know that doing it does involve a lot of duct tape. And I know from Swfdec experience it needs very careful coding to get the error paths not crash and have useful error reporting. As for Bastien's questions: > - There's no public functions to allow seeking > Afaik seeking is just another remote call that needs to be implemented. So this should be a missing feature. > - There's no way to get the size in bytes > I don't think there is a way to query that in the default components. The default components emit an onMetaData event, but I'm pretty sure the usual metadata injectors only inject the time, not the bytesize of the stream. > - There's no way to detect whether a stream is live or not > I did not investigate this when working on RTMP, but afaik this information is not available either. Usually the surrounding SWF file will tell you if it's live. ;)
FWIW, the goal isn't "100% support", but "good enough support" so that streaming videos from sites like BBC, CBC, Hulu and the likes works in Totem/other GStreamer apps.
Note that Plugin Totem Flux (which provides "easy access to some french streams through totem") requires RTMP to get some streams work (canal+ television stream) http://www.manatlan.com/page/totem-plugin-flux
*** Bug 610776 has been marked as a duplicate of this bug. ***
VLC's RTMP plugin http://git.videolan.org/?p=vlc.git;a=tree;f=modules/access/rtmp
Any update about this ?
Starting with rtmpdump 2.2, there is now a rtmp library: "librtmp" (LGPL). It seems to support all we need. Perhaps it would be easier/better to use it? see here: http://rtmpdump.mplayerhq.hu/librtmp.3.html (librtmp description) http://rtmpdump.mplayerhq.hu/ (rtmpdump home page)
I guess I'll look at writing a source element that uses librtmp in the next weeks if nobody is faster. Shouldn't be too hard to get something working ;)
I could also probably finish up what I started if I had any ways of testing it that didn't involve so much guess work...
(In reply to comment #14) > I could also probably finish up what I started if I had any ways of testing it > that didn't involve so much guess work... You mean the flvstreamer plugin? Is it LGPL nowadays? Or did you start a source plugin based on librtmp?
librtmp has seeking support and a function to get the media duration btw
(In reply to comment #16) > librtmp has seeking support and a function to get the media duration btw Then it's probably better than my stuff :)
And to answer my own question, there's some test streams at: http://wiki.multimedia.cx/index.php?title=RTMP
(In reply to comment #17) > (In reply to comment #16) > > librtmp has seeking support and a function to get the media duration btw > > Then it's probably better than my stuff :) Do you want to write a new element for librtmp then?
Created attachment 162509 [details] [review] Add RTMP source plugin
Comment on attachment 162509 [details] [review] Add RTMP source plugin The life-cycle of the RTMP object is horrible. So just a few notes: - code is from rtmpdump-2.2e - upstream code was copied, as they install a *static* library with a pc file - upstream code was cleaned up to compile with GStreamer's warnings on, and re-indented - RTMP_Close() can't be used more than once (it frees some internal buffers) - additional properties (which I removed from the old plugin), probably need adding back, at least the swfURL one or the plugin would only handle rtmpe support. And most of the example streams don't actually work, I believe.
A quick note to say I found: http://curl.haxx.se/mail/lib-2010-05/att-0070/dif3.txt to be useful as a streamed down use of the librtmp code.
(In reply to comment #21) > (From update of attachment 162509 [details] [review]) > The life-cycle of the RTMP object is horrible. So just a few notes: > - upstream code was copied, as they install a *static* library with a pc file > - RTMP_Close() can't be used more than once (it frees some internal buffers) > - additional properties (which I removed from the old plugin), probably need > adding back, at least the swfURL one or the plugin would only handle rtmpe > support. I've asked librtmp upstream about this. Ideally we should just depend on a system version of that library... makes distros more happy I guess ;)
(In reply to comment #21) > (From update of attachment 162509 [details] [review]) > The life-cycle of the RTMP object is horrible. So just a few notes: What do you mean? It's one object per session. > - code is from rtmpdump-2.2e > - upstream code was copied, as they install a *static* library with a pc file pkg-config stuff was added to ease integration with mplayer. I suggest you use "make XCFLAGS=-fPIC" to build a library that can be linked into shared code, that's what I use for libcurl.so. Since the API is not frozen yet, it is too soon to be discussing a shared library target for librtmp. > - upstream code was cleaned up to compile with GStreamer's warnings on, and > re-indented The code uses GNU indent style. Frankly I prefer K&R style but it is what it is. > - RTMP_Close() can't be used more than once (it frees some internal buffers) RTMP_Close() frees everything associated with a session. What else would you expect it to do? > - additional properties (which I removed from the old plugin), probably need > adding back, at least the swfURL one or the plugin would only handle rtmpe > support. I believe it would be a mistake to add specific support for individual librtmp options to applications; the maintenance burden will be pretty significant since new requirements turn up pretty frequently. Better to just take advantage of RTMP_SetupURL() and tack on arbitrary options to the URL. Since the curl code just does a straight dump (no seeking) it's probably not the best model. You should also take a look at the ffmpeg support, which supports seeking. http://git.ffmpeg.org/?p=ffmpeg;a=blob;f=libavformat/librtmp.c;h=dd7640aaebaf94315ba153835d3daa66ea77bb81;hb=HEAD The XBMC patch might also be illustrative http://trac.xbmc.org/ticket/8971
(In reply to comment #24) > (In reply to comment #21) > > (From update of attachment 162509 [details] [review] [details]) > > The life-cycle of the RTMP object is horrible. So just a few notes: > > What do you mean? It's one object per session. You need a backing RTMP to use RTMP_SetupURL(), and that means re-parsing the URL everytime you disconnect/reconnect. I would have expected a separate URL object for example. Note that RTMP_SetupURL() modifies the passed string in place, but you don't know whether it takes ownership of the string or not. > > - code is from rtmpdump-2.2e > > - upstream code was copied, as they install a *static* library with a pc file > > pkg-config stuff was added to ease integration with mplayer. I suggest you use > "make XCFLAGS=-fPIC" to build a library that can be linked into shared code, > that's what I use for libcurl.so. > > Since the API is not frozen yet, it is too soon to be discussing a shared > library target for librtmp. You could write that in text, and have breakage expected. Having a static library doesn't help here. > > - upstream code was cleaned up to compile with GStreamer's warnings on, and > > re-indented > > The code uses GNU indent style. Frankly I prefer K&R style but it is what it > is. I also had to do quite a few code changes (private functions not marked as static, declarations of functions which don't take arguments not having void in their arguments, quite a few problems with const char * vs. char *). Let me know if you want those upstream, and I'll send you a patch. The indentation is a GStreamer-specific requirement. > > - RTMP_Close() can't be used more than once (it frees some internal buffers) > > RTMP_Close() frees everything associated with a session. What else would you > expect it to do? Not the same thing I'd expect from RTMP_Free()? :) > > - additional properties (which I removed from the old plugin), probably need > > adding back, at least the swfURL one or the plugin would only handle rtmpe > > support. > > I believe it would be a mistake to add specific support for individual librtmp > options to applications; the maintenance burden will be pretty significant > since new requirements turn up pretty frequently. Better to just take advantage > of RTMP_SetupURL() and tack on arbitrary options to the URL. OK. I'm only familiar with the RTMP protocol from my earlier attempts, but I agree. If it's not necessary to use additional arguments, that means it'll work better out of the box. > Since the curl code just does a straight dump (no seeking) it's probably not > the best model. You should also take a look at the ffmpeg support, which > supports seeking. > > http://git.ffmpeg.org/?p=ffmpeg;a=blob;f=libavformat/librtmp.c;h=dd7640aaebaf94315ba153835d3daa66ea77bb81;hb=HEAD I was looking for it yesterday and couldn't find it. Thanks. > The XBMC patch might also be illustrative > > http://trac.xbmc.org/ticket/8971 Cool.
(In reply to comment #25) > (In reply to comment #24) > > (In reply to comment #21) > > > (From update of attachment 162509 [details] [review] [details] [details]) > > > The life-cycle of the RTMP object is horrible. So just a few notes: > > > > What do you mean? It's one object per session. > > You need a backing RTMP to use RTMP_SetupURL(), and that means re-parsing the > URL everytime you disconnect/reconnect. Since RTMP URLs frequently include an expiring authentication token, it's unlikely in practice that you can disconnect and then reconnect with the same URL. > Note that RTMP_SetupURL() modifies the passed string in place, but you don't > know whether it takes ownership of the string or not. Hm, yeah, actually there is no need for it to be modifying the string. I'll fix that. > > > - code is from rtmpdump-2.2e > > > - upstream code was copied, as they install a *static* library with a pc file > > > > pkg-config stuff was added to ease integration with mplayer. I suggest you use > > "make XCFLAGS=-fPIC" to build a library that can be linked into shared code, > > that's what I use for libcurl.so. > > > > Since the API is not frozen yet, it is too soon to be discussing a shared > > library target for librtmp. > > You could write that in text, and have breakage expected. Having a static > library doesn't help here. Pretty sure that's already clearly stated on the web site. Given that the librtmp code originated as a bunch of files linked directly into the rtmpdump command, the move to a self-contained library has probably missed a few things here and there. > I also had to do quite a few code changes (private functions not marked as > static, declarations of functions which don't take arguments not having void in > their arguments, quite a few problems with const char * vs. char *). > > Let me know if you want those upstream, and I'll send you a patch. Please do, thanks. > > The indentation is a GStreamer-specific requirement. > > > > - RTMP_Close() can't be used more than once (it frees some internal buffers) > > > > RTMP_Close() frees everything associated with a session. What else would you > > expect it to do? > > Not the same thing I'd expect from RTMP_Free()? :) Originally there was no RTMP_Alloc/RTMP_Free; I added that later so we can start hiding the RTMP structure from applications. So since there was only RTMP_Close, it had to do all cleanup.
PS: I've found these forums to be a good source of test streams: http://stream-recorder.com/forum/streaming-media-recording-forum-f3.html
I'm working on this now, starting with Bastien's patch.
I've committed it to gst-plugins-bad now. This should be a good start for any further improvements and most streams from the multimedia.cx wiki are working with this already. commit c3d10ed72a34e6d256f8a4e27cb17fc106ab0bf5 Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> Date: Fri Jun 4 22:04:53 2010 +0200 rtmpsrc: Major cleanup and reorganization commit 547f037ea4214846255ca13f7e0d1a5107e02413 Author: Sebastian Dröge <sebastian.droege@collabora.co.uk> Date: Fri Jun 4 08:14:42 2010 +0200 rtmp: Move to ext and drop internal librtmp copy We really don't want this in gst-plugins-bad because of legal complexities around RTMP and possible problems for distributions. Add README that explains how to build librtmp to be suitable for linking to the GStreamer plugin. commit b87668e143b2a0208d3d9f474b98dc3d661100b2 Author: Bastien Nocera <hadess@hadess.net> Date: Wed Jun 2 00:45:06 2010 +0100 rtmp: Add RTMP source plugin https://bugzilla.gnome.org/show_bug.cgi?id=566604
I should probably add that I'm going to improve it in the next days ;)
*** Bug 719527 has been marked as a duplicate of this bug. ***
ok this already has been reported so will any body tell me how to compile rtmp + gstreamer with or without cerbero on mac OS 10.8.5