Announcement

Collapse
No announcement yet.

[Sorta' Solved] Can you help me make the Songbird sing?

Collapse
This topic is closed.
X
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    [Sorta' Solved] Can you help me make the Songbird sing?

    I've been watching Songbird since its pre-0.1 days (2 or 3 years ago). I decided to install the most recent 0.4 pre-release snapshot, and am trying to configure it to play my favorite radio station, which uses .asx (wma) streaming. I found how to configure it to play my .wma files (which works), but cannot figure out how to get .asx playback. Songbird uses Gstreamer as it's backend, which supports .asx files, so it shouldn't be too large of a project (I'm just not sure how to do it).

    Edit: The config file looks like this:
    /*
    //
    // BEGIN SONGBIRD GPL
    //
    // This file is part of the Songbird web player.
    //
    // Copyright(c) 2005-2008 POTI, Inc.
    // http://songbirdnest.com
    //
    // This file may be licensed under the terms of of the
    // GNU General Public License Version 2 (the "GPL").
    //
    // Software distributed under the License is distributed
    // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
    // express or implied. See the GPL for the specific language
    // governing rights and limitations.
    //
    // You should have received a copy of the GPL along with this
    // program. If not, go to http://www.gnu.org/licenses/gpl.html
    // or write to the Free Software Foundation, Inc.,
    // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
    //
    // END SONGBIRD GPL
    //
    */

    /**
    * \file coreGStreamerSimple.js
    * \brief The CoreWrapper implementation for the GStreamer simple component
    * \sa sbICoreWrapper.idl coreBase.js
    */

    /**
    * \class CoreGStreamerSimple
    * \brief The CoreWrapper for the simple GStreamer Simple component
    * \sa CoreBase
    */
    function CoreGStreamerSimple()
    {
    this._object = null;
    this._url = "";
    this._id = "";
    this._paused = false;
    this._oldVolume = 0;
    this._muted = false;

    this._mediaUrlExtensions = ["mp3", "ogg", "flac", "mpc", "wav", "m4a", "m4v",
    "wmv", "asf", "avi", "mov", "mpg", "mp4", "ogm",
    "mp2", "mka", "mkv", "wma"];

    this._mediaUrlSchemes = ["mms", "rstp"];

    this._videoUrlExtensions = ["wmv", "asf", "avi", "mov", "mpg", "m4v", "mp4",
    "mp2", "mpeg", "mkv", "ogm"];

    this._unsupportedExtensions = [];

    this._mediaUrlMatcher = new ExtensionSchemeMatcher(this._mediaUrlExtensions,
    this._mediaUrlSchemes);
    this._videoUrlMatcher = new ExtensionSchemeMatcher(this._videoUrlExtensions,
    []);
    this._uriChecker = null;
    this._lastPlayStart = null;
    };

    // inherit the prototype from CoreBase
    CoreGStreamerSimple.prototype = new CoreBase();

    // set the constructor so we use ours and not the one for CoreBase
    CoreGStreamerSimple.prototype.constructor = CoreGStreamerSimple();

    CoreGStreamerSimple.prototype.playURL = function ( aURL )
    {
    this._verifyObject();
    this._checkURL(aURL);

    if (!aURL) {
    throw Components.results.NS_ERROR_INVALID_ARG;
    }

    aURL = this.sanitizeURL(aURL);
    this._paused = false;

    try
    {
    if(this._object.isPlaying || this._object.isPaused)
    {
    this._object.stop();
    }

    if (window.fullScreen)
    {
    window.fullScreen = !window.fullScreen;
    if (this._object.fullscreen) {
    this._object.fullscreen = false;
    }
    }

    var ioService =
    Components.classes["@mozilla.org/network/io-service;1"]
    .getService(Components.interfaces.nsIIOService);

    var uri = ioService.newURI(aURL, null, null);

    // If this is a local file, just play it
    if (uri instanceof Components.interfaces.nsIFileURL) {
    this._object.uri = aURL;
    this._object.play();
    this._lastPlayStart = new Date();
    return true;
    }
    else {
    // Resolve the network URL
    return this._resolveRedirectsAndPlay(uri);
    }

    }
    catch(e)
    {
    this.LOG(e);
    }

    return true;
    };

    CoreGStreamerSimple.prototype._resolveRedirectsAnd Play = function(aURI) {

    // Cancel any old checkers
    if (this._uriChecker) {
    this._uriChecker = null;
    }

    // Make a new uriChecker and initialize it
    var uriChecker =
    Components.classes["@mozilla.org/network/urichecker;1"]
    .createInstance(Components.interfaces.nsIURIChecke r);
    uriChecker.init(aURI);

    // Save it away so we can cancel if necessary. Can't do this until after the
    // init call.
    this._uriChecker = uriChecker;

    // And begin the check
    uriChecker.asyncCheck(this, null);

    return true;
    };

    CoreGStreamerSimple.prototype.play = function ()
    {
    this._verifyObject();

    this._paused = false;

    try
    {
    this._object.play();
    this._lastPlayStart = new Date();
    }
    catch(e)
    {
    this.LOG(e);
    }

    return true;
    };

    CoreGStreamerSimple.prototype.pause = function ()
    {
    if( this._paused )
    return this._paused;

    this._verifyObject();

    try
    {
    this._object.pause();
    }
    catch(e)
    {
    this.LOG(e);
    }

    this._paused = true;

    return this._paused;
    };

    CoreGStreamerSimple.prototype.stop = function ()
    {
    this._verifyObject();

    try
    {
    this._object.stop();
    this._paused = false;
    }
    catch(e)
    {
    this.LOG(e);
    }

    return true;
    };

    CoreGStreamerSimple.prototype.getPlaying = function ()
    {
    this._verifyObject();
    var playing = (this._object.isPlaying || this._paused) && (!this._object.isAtEndOfStream);
    return playing;
    };

    CoreGStreamerSimple.prototype.getPlayingVideo = function ()
    {
    this._verifyObject();
    return this._object.isPlayingVideo;
    };

    CoreGStreamerSimple.prototype.getPaused = function ()
    {
    this._verifyObject();
    return this._paused;
    };

    CoreGStreamerSimple.prototype.getLength = function ()
    {
    this._verifyObject();
    var playLength = 0;

    try
    {
    if(this._object.lastErrorCode > 0) {
    return -1;
    }
    else if(!this.getPlaying()) {
    playLength = 0;
    }
    else {
    playLength = this._object.streamLength / (1000 * 1000);
    }
    }
    catch(e)
    {
    if(e.result == Components.results.NS_ERROR_NOT_AVAILABLE)
    {
    return -1;
    }
    else
    {
    this.LOG(e);
    }
    }

    return playLength;
    };

    CoreGStreamerSimple.prototype.getPosition = function ()
    {
    this._verifyObject();
    var curPos = 0;

    var position = -1;
    try {
    position = this._object.position;
    }
    catch (e) {
    if(e.result != Components.results.NS_ERROR_NOT_AVAILABLE) {
    Components.util.reportError(e);
    }
    }

    if(this._object.lastErrorCode > 0) {
    curPos = -1;
    }
    else if(this._object.isAtEndOfStream || !this.getPlaying()) {
    curPos = 0;
    }
    else if(position > 0) {
    curPos = Math.round(position / (1000 * 1000));
    }
    else {
    // If bufferingPercent is > 0 and < 100, we know we are trying to play
    // a remote stream that is buffering. While this is happening,
    // subsitute playback position for the number of milliseconds since play
    // was requested. This will make playlistplayback think that the file
    // is playing and will prevent it from thinking that there is a problem.
    if (this._object.bufferingPercent > 0 &&
    this._object.bufferingPercent < 100) {
    curPos = (new Date()) - this._lastPlayStart;
    }
    }

    return curPos;
    };

    CoreGStreamerSimple.prototype.setPosition = function ( pos )
    {
    this._verifyObject();

    try
    {
    this._object.seek( pos * (1000 * 1000) );
    }
    catch(e)
    {
    this.LOG(e);
    }
    };

    CoreGStreamerSimple.prototype.getVolume = function ()
    {
    this._verifyObject();
    return Math.round(this._object.volume * 255);
    };

    CoreGStreamerSimple.prototype.setVolume = function ( volume )
    {
    this._verifyObject();

    if ((volume < 0) || (volume > 255))
    throw Components.results.NS_ERROR_INVALID_ARG;

    this._object.volume = volume / 255;
    };

    CoreGStreamerSimple.prototype.getMute = function ()
    {
    this._verifyObject();
    return this._muted;
    };

    CoreGStreamerSimple.prototype.setMute = function ( mute )
    {
    this._verifyObject();

    if(mute)
    {
    this._oldVolume = this.getVolume();
    this._muted = true;
    }
    else
    {
    this.setVolume(this._oldVolume);
    this._muted = false;
    }
    };

    CoreGStreamerSimple.prototype.getMetadata = function ( key )
    {
    this._verifyObject();
    var rv;

    switch(key) {
    case "title":
    rv = this._object.title;
    break;
    case "album":
    rv = this._object.album;
    break;
    case "artist":
    rv = this._object.artist;
    break;
    case "genre":
    rv = this._object.genre;
    break;
    case "url": {
    // Special case for URL... Need to make sure we hand back a complete URI.
    var ioService =
    Components.classes[IOSERVICE_CONTRACTID].getService(nsIIOService);
    var uri;
    try {
    // See if it is a file, first.
    var file =
    Components.classes["@mozilla.org/file/local;1"]
    .createInstance(Components.interfaces.nsILocalFile );
    file.initWithPath(this._object.uri);
    var fileHandler =
    ioService.getProtocolHandler("file")
    .QueryInterface(Components.interfaces.nsIFileProto colHandler);
    var url = fileHandler.getURLSpecFromFile(file);
    uri = ioService.newURI(url, null, null);
    }
    catch (err) { }

    if (!uri) {
    try {
    // See if it is a regular URI
    uri = ioService.newURI(this._object.uri, null, null);
    }
    catch (err) { };
    }

    if (uri)
    rv = uri.spec;
    }
    break;
    default:
    rv = "";
    break;
    }

    return rv;
    };

    CoreGStreamerSimple.prototype.goFullscreen = function ()
    {
    this._verifyObject();
    window.fullScreen=!window.fullScreen;
    if (!this._object.fullscreen)
    this._object.fullscreen = true;
    else
    this._object.fullscreen = false;
    };


    CoreGStreamerSimple.prototype.isMediaURL = function ( aURL )
    {
    return this._mediaUrlMatcher.match(aURL);
    }

    CoreGStreamerSimple.prototype.isVideoURL = function ( aURL )
    {
    return this._videoUrlMatcher.match(aURL);
    }

    CoreGStreamerSimple.prototype.getSupportedFileExte nsions = function ()
    {
    return new StringArrayEnumerator(this._mediaUrlExtensions);
    }

    CoreGStreamerSimple.prototype.getSupportForFileExt ension = function(aFileExtension)
    {
    // Strip the beginning '.' if it exists and make it lowercase
    var extension =
    aFileExtension.charAt(0) == "." ? aFileExtension.slice(1) : aFileExtension;
    extension = extension.toLowerCase();

    // TODO: do something smarter here
    if (this._mediaUrlExtensions.indexOf(extension) > -1)
    return 1;
    else if (this._unsupportedExtensions.indexOf(extension) > -1)
    return -1;

    return 0; // We are the default handler for whomever.
    };

    CoreGStreamerSimple.prototype.onStartRequest = function(request, context)
    {
    // Nothing to do here.
    };

    CoreGStreamerSimple.prototype.onStopRequest = function(request, context, status)
    {
    if (request != this._uriChecker) {
    return;
    }

    if (status == NS_BINDING_SUCCEEDED) {
    // Clear immediately so we can't try to cancel it anymore
    this._uriChecker = null;

    var uriChecker =
    request.QueryInterface(Components.interfaces.nsIUR IChecker);
    var url = uriChecker.baseChannel.URI.spec;

    this._url = url;
    this._object.uri = url;
    this._object.play();
    this._lastPlayStart = new Date();
    }
    };

    /**
    * See nsISupports.idl
    */
    CoreGStreamerSimple.prototype.QueryInterface = function(iid) {
    if (!iid.equals(Components.interfaces.sbICoreWrapper) &&
    !iid.equals(nsIRequestObserver) &&
    !iid.equals(Components.interfaces.nsISupports))
    throw Components.results.NS_ERROR_NO_INTERFACE;
    return this;
    };

    /**
    * ----------------------------------------------------------------------------
    * Global variables and autoinitialization.
    * ----------------------------------------------------------------------------
    */

    try {
    var gGStreamerSimpleCore = new CoreGStreamerSimple();
    }
    catch(err) {
    dump("ERROR!!! coreGStreamerSimple failed to create properly.");
    }

    /**
    * This is the function called from a document onload handler to bind everything as playback.
    */
    function CoreGStreamerSimpleDocumentInit( id )
    {
    try
    {
    var gPPS = Components.classes["@songbirdnest.com/Songbird/PlaylistPlayback;1"]
    .getService(Components.interfaces.sbIPlaylistPlayb ack);
    var videoElement = document.getElementById( id );
    gGStreamerSimpleCore.setId("GStreamerSimple1");
    var gstSimple = Components.classes["@songbirdnest.com/Songbird/Playback/GStreamer/Simple;1"]
    .createInstance(Components.interfaces.sbIGStreamer Simple);
    gstSimple.init(videoElement);
    gGStreamerSimpleCore.setObject(gstSimple);
    gPPS.addCore(gGStreamerSimpleCore, true);
    registeredCores.push(gGStreamerSimpleCore);
    }
    catch ( err )
    {
    dump( "\n!!! coreGStreamerSimple failed to bind properly\n" + err );
    }
    };
    Asus G1S-X3:
    Intel Core2 Duo T7500, Nvidia GeForce 8600M GT, 4Gb PC2-5300, 320Gb Hitachi 7k320, Linux ( )

    #2
    Re: Can you help me make the Songbird sing?

    Did you try simply adding "asx" to:
    Code:
     this._mediaUrlExtensions = ["mp3", "ogg", "flac", "mpc", "wav", "m4a", "m4v",
                   "wmv", "asf", "avi", "mov", "mpg", "mp4", "ogm",
                   "mp2", "mka", "mkv", "wma"];
    Windows no longer obstructs my view.
    Using Kubuntu Linux since March 23, 2007.
    "It is a capital mistake to theorize before one has data." - Sherlock Holmes

    Comment


      #3
      Re: Can you help me make the Songbird sing?

      do you have all the gstreamer plugins/etc installed? A quick search on songird's site shows me this:
      http://publicsvn.songbirdnest.com/wi...#Ubuntu6.06LTS
      Though it is for Dapper, the package names are basically the same
      If you install all the packages listed in the Ubuntu section, it might work (though it didn't for me, but I did not hack mine for wma stuff

      Comment


        #4
        Re: Can you help me make the Songbird sing?

        and it still does not work

        Comment


          #5
          Re: Can you help me make the Songbird sing?

          Originally posted by Snowhog
          Did you try simply adding "asx" to:
          Code:
           this._mediaUrlExtensions = ["mp3", "ogg", "flac", "mpc", "wav", "m4a", "m4v",
                         "wmv", "asf", "avi", "mov", "mpg", "mp4", "ogm",
                         "mp2", "mka", "mkv", "wma"];
          Yes, I tried that; Songbird will acknowledge the .asx file, and add it to the playlist, but can't play it. I've tried various different combinations, but to no avail. Both Songbird and Gstreamer are supposed support the .asx format, so there must be some way to get playback.

          do you have all the gstreamer plugins/etc installed?
          Yes, I have all the Gstreamer plugins and libraries in the repos installed. I just guess it hasn't been properly configured for .asx playback yet.
          Asus G1S-X3:
          Intel Core2 Duo T7500, Nvidia GeForce 8600M GT, 4Gb PC2-5300, 320Gb Hitachi 7k320, Linux ( )

          Comment


            #6
            Re: Can you help me make the Songbird sing?

            Don't know that I can provide any clarity, but maybe I can give some clues in the search. I believe that asx (like some others in your list, ogm for example) is a container format as opposed to a file format. I don't think you are actually playing the asx, you are parsing that file and sending audio and/or video to the appropriate engine/codec to be played. I would check to see what the asx contains. If you are playing wma's sucessfully, maybe it is a wmv or other M$ format that is not working yet.

            I followed Songbird for quite a while, but got frustrated with the ridiculously slow pace of development, particularly considering the hype and commercialization. It seemed to me that if they would put half as much effort into the app as they did their website, it would be useful by now. For me it still is not even a distant second to amarok, but oh well. Good luck.

            Comment


              #7
              Re: Can you help me make the Songbird sing?

              I believe that asx (like some others in your list, ogm for example) is a container format as opposed to a file format.
              I think you're right . . . here is what the file contains:

              <ASX version = "3.0">
              <TITLE>RadioU</TITLE>
              <AUTHOR>RadioU</AUTHOR>
              <COPYRIGHT>(c)2007 Spirit Communications, Inc.</COPYRIGHT>
              <entry>
              <ref HREF="http://geohit.andomedia.com/geo/postHit.asp?s=3499" />
              </entry>
              <ENTRY>
              <TITLE>Where Music Is Going</TITLE>
              <AUTHOR>RadioU</AUTHOR>
              <COPYRIGHT>(c)2007 Spirit Communications, Inc.</COPYRIGHT>
              <REF HREF = "http://nyc04.egihosting.com/749252" />
              <PARAM name="HTMLView" value="http://tvulive.com/player/ASXPage.html"/>
              </ENTRY>
              </ASX>
              I threw "http://nyc04.egihosting.com/749252" into Firefox's address bar just to see what would turn up, and I got a download window stating it's an ASF file. Songbird is supposed to support ASF playback I also tested "http://geohit.andomedia.com/geo/postHit.asp?s=3499", which turned out to be a WMA file, which is also supposed to be supported by Songbird (with a little hacking, anyway). Does anything stand out as peculiar?

              It seemed to me that if they would put half as much effort into the app as they did their website, it would be useful by now.
              True, I guess they got a little carried away with those nice Macs They're supposed to release 1.0 sometime within the next couple of months, so cross your fingers :P

              Edit: Do you think there's a misconfigured demuxer somewhere? KMPlayer tranlates the file into "mmsh://nyc04.egihosting.com/749252", which it easily plays (Amarok has trouble with ASX files too, but it uses Xine as compared to GStreamer).

              Another Edit: I know MPlayer can't play DRM'd files, do you think that could be the problem with Songbird?
              Asus G1S-X3:
              Intel Core2 Duo T7500, Nvidia GeForce 8600M GT, 4Gb PC2-5300, 320Gb Hitachi 7k320, Linux ( )

              Comment


                #8
                Re: Can you help me make the Songbird sing?

                I've done a little research, and determined I would have to really do some serious hacking to get Songbird to play .asx files. I found an old Songbird to-do list that stated "Get rid of asx on Linux" - huh It was speaking of Songbird 0.2, so I googled around and found an old tarball for v0.2; I downloaded and examined its config, and sure enough, ".asx" was listed. So I scanned the file - nothing bad - and ran the app. It was sort of a "blast from the past", if you know what I mean, but it didn't play the .asx file either.

                As such, I've come to the conclusion that Songbird was never able to play .asx files (in Linux any way), and that it is a work in progress. I guess I'll just have to wait another couple of years to play my favorite radio station with Songbird :P
                Asus G1S-X3:
                Intel Core2 Duo T7500, Nvidia GeForce 8600M GT, 4Gb PC2-5300, 320Gb Hitachi 7k320, Linux ( )

                Comment

                Working...
                X