Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-15468] iOS: Titanium.Media.AudioPlayer needs an error event

GitHub Issuen/a
TypeNew Feature
PriorityCritical
StatusClosed
ResolutionFixed
Resolution Date2015-06-01T21:46:09.000+0000
Affected Version/sn/a
Fix Version/sn/a
ComponentsTiAPI
LabelsAudioPlayer, TSP, error, event
Reporterkosso
AssigneeEric Merriman
Created2013-10-01T15:05:27.000+0000
Updated2017-03-21T21:01:46.000+0000

Description

Titanium.Media.AudioPlayer really needs a proper error event. 'Change' and 'progress' aren't enough. Currently, if a stream is broken, or (as is often the case) has the wrong buffer size set (as can be demonstrated in the KitchenSink remote streaming example) we only forced the same alert "Unable to configure network read stream". This error info isn't very useful. Debug logs shows more info logged by AudioStreamer.m which provides more info eg : "Audio packets are larger than kAQBufSize."

Comments

  1. kosso 2014-12-11

    Still no activity on this. If a stream fails to start() the "File Error: Unable to configure network read stream" alert pops up and there's no way get rid of that, or catch anything to provide a better message/retry.
  2. kosso 2014-12-19

    This looks to be a simple fix on iOS. The AudioStreamerCUR.m file has a failWithErrorCode method which is throwing up the error alert. This just needs to be fired back in an error event.
  3. kosso 2014-12-19

    In fact, there is still a silly amount of disparity between iOS and Android, when it comes to the AudioPlayer. State codes differ. iOS has no setTime() ability. Android seems to only fire the 'complete' event. etc. I'm sure these were previously addressed a while ago.
  4. kosso 2015-01-15

    It would also be very useful to detect when the audioPlayer (for example, playing a radio stream in the background) is 'interrupted' by things like an Alarm (or any other audio notification), audio in another app 'stealing' the session, Siri, etc. - Currently, after the audio is interrupted, it does not recover afterwards. I have used a module which uses CoreTelephony to detect when the stream is interrupted (app paused) by a phone call and have been able to stop/resume my stream when that occurs.
  5. kosso 2015-02-20

    More on this: I see that the original AudioStreamer implementation by Steve Tramer was a modification of some popular code by Matt Gallagher. Recently, while looking for a solution to obtaining now-playing metadata from ShoutCast stream, I've come across another modified version of the AudioStreamer classes which will detect and read the 'Icy-Metadata' if present. It would be great to add this patch to our AudioPlayer if possible. https://code.google.com/p/audiostreamer-meta/ This solution is based on an article here, which explains how metadata is streamed by ShoutCast. http://www.smackfu.com/stuff/programming/shoutcast.html Thanks.
  6. kosso 2015-02-20

    update : There is a much, much more recent fork of the AudioStreamer classes here, which has built-in support for Shoutcast metadata, ID3 tags, seeking and also playlists (Ti devs often use the Media.videoPlayer for playlists .m3u etc.) https://github.com/alexcrichton/AudioStreamer/tree/master/AudioStreamer Please can we have a solution based around this? It would be a huge, huge improvement to the very old methods we currently have.
  7. Ingo Muschenetz 2015-02-20

    If someone is willing/able to contribute a solution to this, we would be glad to assist.
  8. kosso 2015-02-20

    If I knew how to do it, I would (I'm an extreme novice when it comes to Objective-C) ;) I've done the research bit ;)
  9. kosso 2015-04-14

    Hi, I seen the status of this update a few times recently. Is there a rough ETA of when this might be fixed? I have a radio station app to get updated which really needs this as soon as possible. Thanks.
  10. Chee Kiat Ng 2015-05-28

    PR here: https://github.com/appcelerator/titanium_mobile/pull/6879 Added iOS error event, as well as documented together with Android. Also removed alert dialog that shows generic error. Users are now required to process the returned error event.

    Sample Code (same as documentation, but added error event listener)

        var win = Titanium.UI.createWindow({  
            title:'Audio Test',
            backgroundColor:'#fff',
            layout: 'vertical'
        });
        
        var startStopButton = Titanium.UI.createButton({
            title:'Start/Stop Streaming',
            top:10,
            width:200,
            height:40
        });
        
        var pauseResumeButton = Titanium.UI.createButton({
            title:'Pause/Resume Streaming',
            top:10,
            width:200,
            height:40,
            enabled:false
        });
        
        win.add(startStopButton);
        win.add(pauseResumeButton);
        
        // allowBackground: true on Android allows the 
        // player to keep playing when the app is in the 
        // background.
        var audioPlayer = Ti.Media.createAudioPlayer({ 
            url: 'http://www.tonycuffe.com/mp3/girlwho_lo.mp3',
            allowBackground: true
        });           
        
        startStopButton.addEventListener('click',function() {
            // When paused, playing returns false.
            // If both are false, playback is stopped.
            if (audioPlayer.playing || audioPlayer.paused)
            {
                audioPlayer.stop();
                pauseResumeButton.enabled = false;
                if (Ti.Platform.name === 'android')
                { 
                    audioPlayer.release();
                }   
            }
            else
            {
                audioPlayer.start();
                pauseResumeButton.enabled = true;
            }
        });
        
        pauseResumeButton.addEventListener('click', function() {
            if (audioPlayer.paused) {
                audioPlayer.start();
            }
            else {
                audioPlayer.pause();
            }
        });
        
        audioPlayer.addEventListener('progress',function(e) {
            Ti.API.info('Time Played: ' + Math.round(e.progress) + ' milliseconds');
        });
        
        audioPlayer.addEventListener('change',function(e)
        {
            Ti.API.info('State: ' + e.description + ' (' + e.state + ')');
        });
        
        audioPlayer.addEventListener('error',function(e)
        {
            Ti.API.info('error: ' + e.error + ' (' + e.code + ')');
        });
        
        win.addEventListener('close',function() {
            audioPlayer.stop();
            if (Ti.Platform.osname === 'android')
            { 
                audioPlayer.release();
            }
        });
        
        win.open();
        

    Steps to test

    1. Run sample app while online 2. *Start / Stop Streaming* 3. While music is playing, go offline

    Expected result

    the error event should be caught, and console prints out error description
  11. kosso 2015-05-28

    +1 Thanks! I'll try this out.
  12. kosso 2015-05-29

    Hi, This worked for me. Also including Pedro's extra fixes since your PR. Thank you! BUT one more thing which just occurred to me also, is the fact that the iOS version of AudioPlayer does not have a 'complete' event. Android does have this event. The 'complete' event should fire when the player reaches the end of a file. Could this also be added? For the sake of parity. Thank you.
  13. Pedro Enrique 2015-06-01

  14. Lee Morris 2017-03-21

    Closing ticket as fixed.

JSON Source