Giter VIP home page Giter VIP logo

audiostreamer's Introduction

A fork of DigitalDJ's AudioStreamer (which is a fork jfricker's AudioStreamer (which is a fork of the original AudioStreamer by mattgallagher))


Forked and cherry-picked to get a number of community addons and fixes:
- Shoutcast metadata [jfricker]
- MIME type detection [andybee]
- HE-AACv2 [idevsoftware]
- Level Metering [idevsoftware]
- NSThread memory leak [mattgallagher]
- Fix alert spam / Invisible alerts by dispatching alerts on the main (GUI) thread instead of the notification thread [sebsto]
- Fix compilation issues in Mac OS X Sample App [sebsto]
- Fix compilation issue when SHOUTCAST_METADAT flag is defined [sebsto]
- Fix iPhone apps crashes in SHOUTCAST_METADATA mode when returning from Background [sebsto]
- Album metadata [nickpack]
- Buffer fill percentage [rayh]
- Possible fix for playing non-VBR WAV streams [isalkind]
- Invalid byte range header fix [whyz]
- Compatibility with OS3.x [bradfordcp]

Fixes and features I've implemented:
- Fixed interruption crashes
- Background buffering
- Play/pause from iPod controls
- Stop all UI updating and timers while backgrounded
- Retina display example
- Support for Pause button in UI
- Local Notifications (outside app) on error




audiostreamer's People

Contributors

andybee avatar bradfordcp avatar jfricker avatar marcboquet avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

audiostreamer's Issues

This old code can cause 'hwiu' problem

commit: c9cbb7b

If quickly change songs with different audio streamer instances, it may cause 'hwiu' problem.

Because When quickly change/skip songs , program first 'stop's current audiostreamer instance, then creates a new instance. But during quick changin, the first instance may be during 'WAITING_FOR_DATA' state, and - (void)stop just returned, and the instance is released. However the old thread start a new audio queue then, the new instance cannot re-start a AQ, returned a 'hwiu'

Reduce number of states

Personally I'm no big fan of too many states at all - and AudioStreamer has too many to make them understand easily.
All those if-clauses that check a bunch of STATES are hard to read and it's easy to sneak errors in.

Some proposals:

AS_WAITING_FOR_DATA could be replaced by AS_BUFFERING at all places (the only difference between both is whether the AudioQueue was created at all, but this info can be obtained directly from the queue-variable).
This might even fix a bug for the 'stop'-method, because this one currently does not react while in the state 'AS_WAITING_FOR_DATA'

AS_FLUSHING_EOF can be omitted - I'd replace it with an enqueueBuffer:(BOOL) flush call which can be called in the special EOF scenario.

Having two states less makes the code much more readable.

current use of background-tasks leads to crashes

You currently use background tasks without expiration handlers.
If a background task expires while the App is in the background, it will be killed by iOS (from my observations it seems like this happens only after 24hours - or when the App is restarted later on)

From the documentation of the expirationHandler:

"A handler to be called shortly before the application’s remaining background time reaches 0. You should use this handler to clean up and mark the end of the background task. Failure to end the task explicitly will result in the termination of the application. The handler is called synchronously on the main thread, thus blocking the application’s suspension momentarily while the application is notified."

Futhermore it should be enough to start exactly one background task when the Queue is stopped. While playing the App will not be suspended (if the App declares 'audio' as it's background mode).

Mac OS X Sample App does not compile

After your last changes to nicely handle background streaming for iOS, the Mac OS X demo application is not compiling anymore.

I made the following modification to correct this - could you please integrate in your repository ?

diff --git a/Classes/AudioStreamer.h b/Classes/AudioStreamer.h
index 2236457..0857f17 100644
--- a/Classes/AudioStreamer.h
+++ b/Classes/AudioStreamer.h
@@ -104,7 +104,9 @@

@interface AudioStreamer : NSObject
{
+#if TARGET_OS_IPHONE
UIBackgroundTaskIdentifier bgTaskId;
+#endif
NSURL *url;

//

diff --git a/Classes/AudioStreamer.m b/Classes/AudioStreamer.m
index 4e8e56a..190cdcd 100644
--- a/Classes/AudioStreamer.m
+++ b/Classes/AudioStreamer.m
@@ -30,7 +30,7 @@
NSString * const ASUpdateMetadataNotification = @"ASUpdateMetadataNotification";
#endif

-static AudioStreamer *__streamer = nil;
+//static AudioStreamer *__streamer = nil;

NSString * const AS_NO_ERROR_STRING = @"No error.";
NSString * const AS_FILE_STREAM_GET_PROPERTY_FAILED_STRING = @"File stream get property failed.";
@@ -1215,7 +1215,9 @@ - (void)pause
else if (state == AS_PAUSED)
{
err = AudioQueueStart(audioQueue, NULL);
+#if TARGET_OS_IPHONE
bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
+#endif
if (err)
{
[self failWithErrorCode:AS_AUDIO_QUEUE_START_FAILED];
@@ -1807,8 +1809,9 @@ - (void)enqueueBuffer
if (self.state == AS_BUFFERING)
{
err = AudioQueueStart(audioQueue, NULL);
+#if TARGET_OS_IPHONE

bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];

+#endif
if (err)
{
[self failWithErrorCode:AS_AUDIO_QUEUE_START_FAILED];
@@ -1821,8 +1824,9 @@ - (void)enqueueBuffer
self.state = AS_WAITING_FOR_QUEUE_TO_START;

                err = AudioQueueStart(audioQueue, NULL);

+#if TARGET_OS_IPHONE

bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];

+#endif
if (err)
{
[self failWithErrorCode:AS_AUDIO_QUEUE_START_FAILED];
@@ -2300,8 +2304,9 @@ - (void)handlePropertyChangeForQueue:(AudioQueueRef)inAQ
propertyID:(AudioQueuePropertyID)inID
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+#if TARGET_OS_IPHONE

UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;

+#endif
@synchronized(self)
{
if (inID == kAudioQueueProperty_IsRunning)
@@ -2327,17 +2332,21 @@ - (void)handlePropertyChangeForQueue:(AudioQueueRef)inAQ
// thread destruction order and seems to avoid this crash bug -- or
// at least I haven't had it since (nasty hard to reproduce error!)
//
+#if TARGET_OS_IPHONE
newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
+#endif

            [NSRunLoop currentRunLoop];

            self.state = AS_PLAYING;

    +#if TARGET_OS_IPHONE
    if (bgTaskId != UIBackgroundTaskInvalid) {
    [[UIApplication sharedApplication] endBackgroundTask: bgTaskId];
    }

            bgTaskId = newTaskId;
    

    +#endif
    }
    else
    {

iOS 3.x compatibility lost

Somewhere along the past updates you've lost compatibility with iOS 3.x by use of the UIBackgroundTaskIdentifier (at least). Not sure if this was on purpose or not, but I believe this all should work without the background stuff anyway. I've so far failed nailing the exact point of inclusion of the background stuff, as I still have a hard time with git. I'm hoping for some iOS 3.x adaptations. :-)

Error: get sometime no sound but always stream...

hello,

it's hard to explain like that and in english...
but I find that when when stream from example: http://radio.virtualdj.com/mp3player/stream.php?foo=bar.mp3

Web got after random time a blank sound... no sound, silence but streaming is continuing. Need to stop de streamer and restart it.

It's very strange, I've try with some other AudioStreamer source on the internet but the problem is still here, and I also test this with the RadioKit SDK (sold some where on the internet) and problem still here too.

Maybe, someone have solution for this ??

Jonathan
Thanks in advance.

iPhone apps crashes in SHOUTCAST_METADATA mode when returning from Background

When returning from background, and using SHOUTCAST_METATDATA, the iPhone demo application is crashing

Reproductible : always
Cause : currentArtist and currentTitle are not properly retained
Modifications :
Declare currentArtist and currentTitle as @Property with 'retain' attribute
in the ViewController .h
@Property (retain) NSString* currentArtist;
@Property (retain) NSString* currentTitle;

In the ViewController.m
Just after @implementation :
@synthesize currentArtist, currentTitle;

and in - (void)metadataChanged:(NSNotification *)aNotification

self.currentArtist = streamArtist;
self.currentTitle = streamTitle;

Unable to play certain streams

Randomly seems to play some streams such as http://96.30.20.155:8006. I tried it on iOS 6 and above, and even on the simulator, all same results. The stream gets stuck in "waiting" status and never plays. For the above mentioned streams this problem happens like 70% of times at least.

EOF while buffering

Hi DigitalDJ, you seem to be the most active contributor to AudioStreamer, that's why I thouht I share my findings here.

I think there is one problem, when AudioStreamer is in the AS_BUFFERING state and then an EOF from the stream turnes up.
The streamer should be put in the AS_FLUSHING_EOF state then (at the same place when an EOF happens while the state is WAITING_FOR_DATA).

Otherwise the last bits of audio will never be streamed.

Can't provide a patch, as my own code did too many changes to the original already.

Spammy & Invisible In-App Alerts

Not sure how to reproduce this 100%

When an error occurs (e.g. loss of connection) sometimes alerts are invisible, causing the UI to be unresponsive, or many alerts appear at the same time, causing the user to press OK more than 2 times. Sometimes it just works as intended, one dismissible alert. Also, local notifications (e.g. alerts while backgrounded) don't seem to suffer from this problem, from what I've seen...

I've found often a phone reboot can fix the issue, so I'm not quite sure of the exact issue.

Anyone have any ideas? Post here, please!

Pause action issue

Hello,

I would suggest the following scenario to test a bug:

Hit play and wait for a few moments
Hit pause - i implemented this action using the pause method in AudioStreamer - and wait a minute or two
Hit the play button again to resume - theas means that the pause method gets called again - and wait a minute

The result will be a AS_STOPPING_EOF state. Even if it's still playing after the second hit play action, i traced that to be just remainings from a buffer. I can't though figure how to resolve this, any suggestions would be appreciated.

Thanks in advance!

Remote Control Events Stop Working

I noticed that when this code is run the main viewController sends itself a message to become the firstResponder making it able to receive remote control events. This works as expected, but the viewController loses its firstResponder status when the text field becomes the firstResponder. Because of this, when this app is run and the text field never becomes firstResponder (ie never tapped by user), the remote control events work as expected. As soon as the text field is tapped, the viewController loses firstResponder status and never gets it back.

The fix is rather simple, just call [self becomeFirstResponder] after the text field resigns firstResponder status.

Maybe a bug

when quickly switch among songs, calling -stop, it may exit -startInternal before calling -failWithErrorCode(in a thread, for example parse bytes thread), however, before exiting -startInternal, state is set as AS_INITIALIZED, but in -failWithError, state is set as AS_STOPPED, so the -stop is in a dead loop.

so before set as AS_STOPPED in failWithError, it should check wheather the state is AS_INITIALIZED.

Audio queue creation failed.

Hi,
I installed icecast2 on a linux server.
I use VLC as test listening and it works; I use also on a web page with ffmp3 flash player and it works with no issue.
Here the link:
http://81.208.58.168:65080/radio

I download this wonderful example to do some test, but I cannot listen anything. It goes straighten to this issue:

2013-09-11 14:53:38.627 iPhoneStreamingPlayer[2463:1307] Error: Error Domain=NSOSStatusErrorDomain Code=1718449215 "The operation couldn’t be completed. (OSStatus error 1718449215.)"
2013-09-11 14:53:46.778 iPhoneStreamingPlayer[2463:1307] Audio queue creation failed. err: fmt? 1718449215

I have absolutely no clue why I got this error, the second line should be the meaning of the code 1718449215

I hope someone can help me, thanks a lot

nibe

SHOUTCAST_METADATA does not compile

When defining SHOUTCAST_METADATA in AudioStreamer.h, the code does not compile.
I corrected this, here is my diff file

diff --git a/Classes/AudioStreamer.h b/Classes/AudioStreamer.h
index 0857f17..22fd1ab 100644
--- a/Classes/AudioStreamer.h
+++ b/Classes/AudioStreamer.h
@@ -11,6 +11,7 @@
// this copyright and permission notice. Attribution in compiled projects is
// appreciated but not required.
//
+#define SHOUTCAST_METADATA

#if TARGET_OS_IPHONE
#import <UIKit/UIKit.h>
@@ -101,6 +102,9 @@

extern NSString * const ASStatusChangedNotification;
extern NSString * const ASPresentAlertWithTitleNotification;
+#ifdef SHOUTCAST_METADATA
+extern NSString * const ASUpdateMetadataNotification;
+#endif

@interface AudioStreamer : NSObject
{
diff --git a/Classes/AudioStreamer.m b/Classes/AudioStreamer.m
index 134ebb8..323634d 100644
--- a/Classes/AudioStreamer.m
+++ b/Classes/AudioStreamer.m
@@ -1283,8 +1283,7 @@ - (void)updateMetaData:(NSString *)metaData
notificationWithName:ASUpdateMetadataNotification
object:self
userInfo:userInfo];

  •   [[NSNotificationCenter defaultCenter]
    
  •    postNotification:notification];
    
  •   [[NSNotificationCenter defaultCenter] postNotification:notification];
    
    }
    #endif

@@ -1422,10 +1421,13 @@ - (void)handleReadFromStream:(CFReadStreamRef)aStream
}
}

          UInt8 bytes[kAQDefaultBufSize];
          CFIndex length;
  •           //UInt8 bytesNoMetaData[kAQDefaultBufSize];
    
  •           //int lengthNoMetaData = 0;
    

    +#ifdef SHOUTCAST_METADATA

  •           UInt8 bytesNoMetaData[kAQDefaultBufSize];
    
  •           int lengthNoMetaData = 0;
    

    +#endif

            @synchronized(self)
            {
    

Problem with Encoding Ä Ö Ü ß

I'm playing a Stream with German Umlaute in the Shoutcast Metadata and for example an Ö= ö

We need a Check for the Encoding in the Shoutcast Metadata i guess, or convert it to UTF-8

Not playing M4A file

Hi, i working on playing audio stream from HTTP it is playing aiff,mp3 and wav fine but not work for M4A. I dont know why it is happening can you please give me a short fix for it?

It will cause a bug?

  • (void)stop
    {
    @synchronized(self)
    {
    if (state == AS_WAITING_FOR_DATA || state == AS_STARTING_FILE_THREAD)
    return;
    ......

Here, if calling stop before during the thread is starting or downloading , the stop do nothing, and will leave a wrong state?

readonly stopReason is not threadsafe

Just synthesizing a readonly stopReason property is not thread-safe.

In all the AudioStreamers-Code the state is set first, followed by the stopReason.
Upon setting the state, the main thread gets a notification - if it then reads the stopReason it might see an old value, as the actual stopReason might have not been set yet.

At least the read-access to the stopReason should be synchronized - so the main-thread won't see stale data.
Or you change the order - set the stopReason first, followed by the state.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.