Edgar Merino
2007-Sep-08 02:00 UTC
[Icecast-dev] Coding in python using shout-python bindings
Hello, I'm creating a module written in python that brings an easy to implement interface for the libshout lib, mainly to provide streaming capabilities to a gnome player called Exaile (http://www.exaile.org). The module is almost done (already available at http://devpower.blogsite.org:8080/archivos/icastplugin.py) but I'm encountering some problems (I believe sync problems): I'll try to explain my self briefly, The module defines a class called Icast, which needs at least an implementation of a Client to work. This Client can be anything, a GUI player (like exaile) or a cmdline app (mpg123), or anything that can be represented as a Client. This Client must define a method (called get_current_track()) to retrieve the current track being played by the client the class interfaces. The Icast class stores a copy of this too in an attribute called current_track When the player changes the track, Icast noticies this by comparing the track information it has stored in current_track with the current song being played at the moment by the client (get_current_track()). The streaming is done by the following block of code: buf = f.read(4096) if len(buf) == 0 return server.send(buf) server.sync() Ok that was the background, on to the problem: After a random period of time, the listening client of the stream stops. At first I thought this was caused because the module had failed sending data to the server, but this was not the case as clicking "play" again in the listening client and checking the stats page of icecast had the stream available. So I tried to trace the bug in the code, and so far I believe it's a syncing problem; when the player performs its first track change everything is ok, but then data is sent to the server faster than the time it takes the track to play in the server player(the interface to the Client, NOT the listening client). The time it stays without sending data to the server increases with every song, I've noticed that when the listening client dies the server didn't receive data for almost 4 - 5 seconds (but the server didn't ask for more, since server.sync() didn't take more time). If this is the correct behaviour of icecast then what should I do to tell the icecast server to wait N seconds before more data can be sent? (server.delay() what is this good for?). If this is not the correct behaviour or the behaviour can be controlled with icecast.xml how should I do it? (I tried setting burst-connect to 0 but got the same behaviour...) I hope I can get some help with this, and excuse my big explanation of the problem and poor way to do it, but english is not my native language and it's been a while since I had a real conversation in this language. Thanks in advance. Edgar Merino
Just a thought: I don't know the python API, but it reminds me of a common "bug"/strange behaviour in other languages (eg PHP): often this happens because one call to "f.read(4096)" is not enough to get the full message. And if I recall exactly, it's no use to increase from 4096 to 8192 or more : it's because the f.read method is async, i.e. one call may not consume all message. So, first you have to check if f.read is async, and if it is, it could help to write something like : while len(buffer) > lastlen: buffer += f.read(4096) lastlen = len(buffer) Hope this helps ! it would be cool if a python binding for libshout was to be released :) 2007/9/8, Edgar Merino <donvodka@gmail.com>:> Hello, > > I'm creating a module written in python that brings an easy to implement > interface for the libshout lib, mainly to provide streaming capabilities > to a gnome player called Exaile (http://www.exaile.org). The module is > almost done (already available at > http://devpower.blogsite.org:8080/archivos/icastplugin.py) but I'm > encountering some problems (I believe sync problems): > > I'll try to explain my self briefly, > The module defines a class called Icast, which needs at least an > implementation of a Client to work. This Client can be anything, a GUI > player (like exaile) or a cmdline app (mpg123), or anything that can be > represented as a Client. This Client must define a method (called > get_current_track()) to retrieve the current track being played by the > client the class interfaces. The Icast class stores a copy of this too > in an attribute called current_track > > When the player changes the track, Icast noticies this by comparing the > track information it has stored in current_track with the current song > being played at the moment by the client (get_current_track()). > > The streaming is done by the following block of code: > buf = f.read(4096) > if len(buf) == 0 > return > server.send(buf) > server.sync() > > Ok that was the background, on to the problem: > After a random period of time, the listening client of the stream stops. > At first I thought this was caused because the module had failed sending > data to the server, but this was not the case as clicking "play" again > in the listening client and checking the stats page of icecast had the > stream available. So I tried to trace the bug in the code, and so far I > believe it's a syncing problem; when the player performs its first track > change everything is ok, but then data is sent to the server faster than > the time it takes the track to play in the server player(the interface > to the Client, NOT the listening client). The time it stays without > sending data to the server increases with every song, I've noticed that > when the listening client dies the server didn't receive data for almost > 4 - 5 seconds (but the server didn't ask for more, since server.sync() > didn't take more time). If this is the correct behaviour of icecast then > what should I do to tell the icecast server to wait N seconds before > more data can be sent? (server.delay() what is this good for?). If this > is not the correct behaviour or the behaviour can be controlled with > icecast.xml how should I do it? (I tried setting burst-connect to 0 but > got the same behaviour...) > > I hope I can get some help with this, and excuse my big explanation of > the problem and poor way to do it, but english is not my native language > and it's been a while since I had a real conversation in this language. > Thanks in advance. > > Edgar Merino > _______________________________________________ > Icecast-dev mailing list > Icecast-dev@xiph.org > http://lists.xiph.org/mailman/listinfo/icecast-dev >
Geoff Shang
2007-Sep-20 14:14 UTC
[Icecast-dev] Coding in python using shout-python bindings
oDDsKool wrote:> it would be cool if a python binding for libshout was to be released :)It was. http://downloads.us.xiph.org/releases/libshout/shout-python-0.2.tar.gz I've not looked at it though. Geoff.
Guillaume Pellerin
2007-Sep-21 05:14 UTC
[Icecast-dev] Coding in python using shout-python bindings
Hi ! These days, I began to write a tool from scratch in python which streams mp3/ogg files to icecast2, randomly or not. D-Fuzz mostly reproduces the behavior of the great Oddsock's Ezstream I've been used for a while. But now, I need more features... Here is the code browser: http://svn.parisson.org/d-fuzz/browser/trunk You can get it with subversion: svn co http://svn.parisson.org/svn/d-fuzz/trunk d-fuzz This app is very young (alpha), but the iterators objects make it very simple and it works great with just one channel per Station (see example/myfuzz.xml). As I'd like to build many sub-channels per station, I've tried to subclass threading.Thread, but this doesn't work very well for the moment with many channels for the same station (have to make the fine Queue...). Advises on this are welcome and any feedback as well !! I hope this will help to understand some of the shout-python API I've included in it... Cheers, Yomguy Edgar Merino wrote:> Hello, > > I'm creating a module written in python that brings an easy to implement > interface for the libshout lib, mainly to provide streaming capabilities > to a gnome player called Exaile (http://www.exaile.org). The module is > almost done (already available at > http://devpower.blogsite.org:8080/archivos/icastplugin.py) but I'm > encountering some problems (I believe sync problems): > > I'll try to explain my self briefly, > The module defines a class called Icast, which needs at least an > implementation of a Client to work. This Client can be anything, a GUI > player (like exaile) or a cmdline app (mpg123), or anything that can be > represented as a Client. This Client must define a method (called > get_current_track()) to retrieve the current track being played by the > client the class interfaces. The Icast class stores a copy of this too > in an attribute called current_track > > When the player changes the track, Icast noticies this by comparing the > track information it has stored in current_track with the current song > being played at the moment by the client (get_current_track()). > > The streaming is done by the following block of code: > buf = f.read(4096) > if len(buf) == 0 > return > server.send(buf) > server.sync() > > Ok that was the background, on to the problem: > After a random period of time, the listening client of the stream stops. > At first I thought this was caused because the module had failed sending > data to the server, but this was not the case as clicking "play" again > in the listening client and checking the stats page of icecast had the > stream available. So I tried to trace the bug in the code, and so far I > believe it's a syncing problem; when the player performs its first track > change everything is ok, but then data is sent to the server faster than > the time it takes the track to play in the server player(the interface > to the Client, NOT the listening client). The time it stays without > sending data to the server increases with every song, I've noticed that > when the listening client dies the server didn't receive data for almost > 4 - 5 seconds (but the server didn't ask for more, since server.sync() > didn't take more time). If this is the correct behaviour of icecast then > what should I do to tell the icecast server to wait N seconds before > more data can be sent? (server.delay() what is this good for?). If this > is not the correct behaviour or the behaviour can be controlled with > icecast.xml how should I do it? (I tried setting burst-connect to 0 but > got the same behaviour...) > > I hope I can get some help with this, and excuse my big explanation of > the problem and poor way to do it, but english is not my native language > and it's been a while since I had a real conversation in this language. > Thanks in advance. > > Edgar Merino > _______________________________________________ > Icecast-dev mailing list > Icecast-dev@xiph.org > http://lists.xiph.org/mailman/listinfo/icecast-dev >