Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Streaming music from web  (Read 3045 times)

0 Members and 1 Guest are viewing this topic.

Pikablu

  • Newbie
  • *
  • Posts: 5
    • View Profile
Streaming music from web
« on: June 17, 2014, 09:53:44 pm »
Are there any examples for streaming music from the web? I've been trying to just pass an HttpResponseStream into the standard Music class, but I end up with a NotSupportedException saying the stream doesn't support seek operations. I'm using a normal ogg file (http://upload.wikimedia.org/wikipedia/en/4/45/ACDC_-_Back_In_Black-sample.ogg).

Am I supposed to do it in some other way, or is it just not supported?

Thanks

Here's my code:

        static void Main(string[] args) {
            RenderWindow window = new RenderWindow(new VideoMode(800, 600), "SFML_App", Styles.Titlebar);

            HttpWebRequest request;

            request = (HttpWebRequest)WebRequest.Create("http://upload.wikimedia.org/wikipedia/en/4/45/ACDC_-_Back_In_Black-sample.ogg");
            Stream stream = request.GetResponse().GetResponseStream();

            SFML.Audio.Music music = new SFML.Audio.Music(stream);
            music.Play();

            while (window.IsOpen()) {
                window.DispatchEvents();
            }
        }
« Last Edit: June 17, 2014, 09:55:36 pm by Pikablu »

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Streaming music from web
« Reply #1 on: June 17, 2014, 10:01:37 pm »
I don't know exactely what you want to do, but I'll guess.
You want to download some sound date from "somewhere" and then play that sound locally.
So how about this; download the sound data to a local memory buffer. Have a soundstream read from that buffer whenever there is a sensible amount of data in it.
You cannot really prevent skips/stops in the sound if the source doesn't provide it fast enough; but you can't really fix that.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Streaming music from web
« Reply #2 on: June 17, 2014, 10:10:46 pm »
I don't know HttpResponseStream but it looks like it could work. Can you tell me more about the NotSupportedException exception? Maybe there's something that can be done in SFML to workaround it. Indeed, the Seek function is not needed if you don't call Music.SetPlayingPosition, which you won't for a music streamed from the internet anyway. I think it should be ok to disable Seek for streams that don't support it.

Edit: I just found the CanSeek property. Could you test it quickly to validate the idea? This must be changed in the StreamAdaptor class.
« Last Edit: June 17, 2014, 10:13:30 pm by Laurent »
Laurent Gomila - SFML developer

Pikablu

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Streaming music from web
« Reply #3 on: June 17, 2014, 10:24:26 pm »
CanSeek seems to be read-only for the stream.

Here's a stack trace of the exception:
   at System.Net.ConnectStream.get_Length()
   at SFML.Window.StreamAdaptor.GetSize(IntPtr userData)
   at SFML.Audio.Music.sfMusic_createFromStream(IntPtr stream)
   at SFML.Audio.Music..ctor(Stream stream)

It fails when getting the length of the stream. Taking a look at the ConnectStream class in .NET (which is what GetResponseStream() returns), it seems to always throw that exception.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Streaming music from web
« Reply #4 on: June 17, 2014, 10:37:52 pm »
Quote
CanSeek seems to be read-only for the stream.
Yes, I was meaning to implement something like this inside SFML.Net:

if (stream.CanSeek)
    stream.Seek(...);

... so that non-seekable streams could work as long as you're not using this feature. But as I write this I realize that it would be useless: if the exception is thrown, it means that the Seek function is called somehow, so the solution would be to check SFML code and find out why it is called, and remove this call if it's not strictly needed. Based on what I've found, it could be done for the Music class.

Quote
It fails when getting the length of the stream
Hmm true, Length is not supported too. I don't know if we can avoid this one, I haven't got full control on it in SFML. It is used deeply inside libsndfile, which is a dependency of SFML. I could investigate though.
« Last Edit: June 17, 2014, 10:40:10 pm by Laurent »
Laurent Gomila - SFML developer

Pikablu

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Streaming music from web
« Reply #5 on: June 17, 2014, 11:33:33 pm »
Thanks! It would be really helpful for me. I'm aware that I can just download the entire file into memory first, but I'm working with fairly large files (200+ mb), so having users wait for the entire file to download before playing would be a pain.

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Streaming music from web
« Reply #6 on: June 18, 2014, 12:10:42 am »
You dont have to download everytinng. Just get a bit and start playing. Then get a bit more etc. Not hard.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
Re: Streaming music from web
« Reply #7 on: June 18, 2014, 07:39:57 am »
You dont have to download everytinng. Just get a bit and start playing. Then get a bit more etc. Not hard.
And guess what, this is exactly what his code does, in a very automatic and elegant way ;)

So yes, he can do it manually with a lot more code, but it would be nice if such a common use case (-> non seekable streams) could work with SFML.

Actually, I'm rewritting the sound file code in SFML, so this is a good opportunity to have a look at this issue.
Laurent Gomila - SFML developer