Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 000930a295 | |||
| 269f335ee4 | |||
| 162d964372 | |||
| ef7f42c97e | |||
| ea9e40b17a | |||
| 9510d74e58 |
@@ -63,22 +63,22 @@
|
||||
[playFromHTTPButton setTitle:@"Play from HTTP" forState:UIControlStateNormal];
|
||||
|
||||
playFromIcecastButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
playFromIcecastButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 50, size.width, size.height);
|
||||
playFromIcecastButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 35, size.width, size.height);
|
||||
[playFromIcecastButton addTarget:self action:@selector(playFromIcecasButtonTouched) forControlEvents:UIControlEventTouchUpInside];
|
||||
[playFromIcecastButton setTitle:@"Play from Icecast" forState:UIControlStateNormal];
|
||||
|
||||
playFromLocalFileButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
playFromLocalFileButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 100, size.width, size.height);
|
||||
playFromLocalFileButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 70, size.width, size.height);
|
||||
[playFromLocalFileButton addTarget:self action:@selector(playFromLocalFileButtonTouched) forControlEvents:UIControlEventTouchUpInside];
|
||||
[playFromLocalFileButton setTitle:@"Play from Local File" forState:UIControlStateNormal];
|
||||
|
||||
queueShortFileButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
queueShortFileButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 150, size.width, size.height);
|
||||
queueShortFileButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 105, size.width, size.height);
|
||||
[queueShortFileButton addTarget:self action:@selector(queueShortFileButtonTouched) forControlEvents:UIControlEventTouchUpInside];
|
||||
[queueShortFileButton setTitle:@"Queue short file" forState:UIControlStateNormal];
|
||||
|
||||
queuePcmWaveFileFromHTTPButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
queuePcmWaveFileFromHTTPButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 280, size.width, size.height);
|
||||
queuePcmWaveFileFromHTTPButton.frame = CGRectMake((320 - size.width) / 2, frame.size.height * 0.10 + 140, size.width, size.height);
|
||||
[queuePcmWaveFileFromHTTPButton addTarget:self action:@selector(queuePcmWaveFileButtonTouched) forControlEvents:UIControlEventTouchUpInside];
|
||||
[queuePcmWaveFileFromHTTPButton setTitle:@"Queue PCM/WAVE from HTTP" forState:UIControlStateNormal];
|
||||
|
||||
@@ -94,7 +94,7 @@
|
||||
[stopButton setTitle:@"Stop" forState:UIControlStateNormal];
|
||||
|
||||
muteButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
|
||||
muteButton.frame = CGRectMake((320 - size.width) - 30, 420, size.width, size.height);
|
||||
muteButton.frame = CGRectMake((320 - size.width) - 30, 430, size.width, size.height);
|
||||
[muteButton addTarget:self action:@selector(muteButtonPressed) forControlEvents:UIControlEventTouchUpInside];
|
||||
[muteButton setTitle:@"Mute" forState:UIControlStateNormal];
|
||||
|
||||
@@ -180,6 +180,17 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioPlayer.currentlyPlayingQueueItemId == nil)
|
||||
{
|
||||
slider.value = 0;
|
||||
slider.minimumValue = 0;
|
||||
slider.maximumValue = 0;
|
||||
|
||||
label.text = @"";
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (audioPlayer.duration != 0)
|
||||
{
|
||||
slider.minimumValue = 0;
|
||||
@@ -194,7 +205,7 @@
|
||||
slider.minimumValue = 0;
|
||||
slider.maximumValue = 0;
|
||||
|
||||
label.text = @"";
|
||||
label.text = [NSString stringWithFormat:@"Live stream %@", [self formatTimeFromSeconds:audioPlayer.progress]];
|
||||
}
|
||||
|
||||
statusLabel.text = audioPlayer.state == STKAudioPlayerStateBuffering ? @"buffering" : @"";
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
CGFloat meterWidth = 0;
|
||||
|
||||
if (audioPlayer.duration != 0)
|
||||
if (audioPlayer.currentlyPlayingQueueItemId != nil)
|
||||
{
|
||||
slider.minValue = 0;
|
||||
slider.maxValue = audioPlayer.duration;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "StreamingKit"
|
||||
s.version = "0.1.23"
|
||||
s.version = "0.1.25"
|
||||
s.summary = "A fast and extensible audio streamer for iOS and OSX with support for gapless playback and custom (non-HTTP) sources."
|
||||
s.homepage = "https://github.com/tumtumtum/StreamingKit/"
|
||||
s.license = 'MIT'
|
||||
|
||||
@@ -164,6 +164,50 @@
|
||||
return audioFileTypeHint;
|
||||
}
|
||||
|
||||
-(NSDictionary*) parseIceHeader:(NSData*)headerData
|
||||
{
|
||||
NSMutableDictionary* retval = [[NSMutableDictionary alloc] init];
|
||||
NSCharacterSet* characterSet = [NSCharacterSet characterSetWithCharactersInString:@"\r\n"];
|
||||
NSString* fullString = [[NSString alloc] initWithData:headerData encoding:NSUTF8StringEncoding];
|
||||
NSArray* strings = [fullString componentsSeparatedByCharactersInSet:characterSet];
|
||||
|
||||
httpHeaders = [NSMutableDictionary dictionary];
|
||||
|
||||
for (NSString* s in strings)
|
||||
{
|
||||
if (s.length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([s hasPrefix:@"ICY "])
|
||||
{
|
||||
NSArray* parts = [s componentsSeparatedByString:@" "];
|
||||
|
||||
if (parts.count >= 2)
|
||||
{
|
||||
self->httpStatusCode = [parts[1] intValue];
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
NSRange range = [s rangeOfString:@":"];
|
||||
|
||||
if (range.location == NSNotFound)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
NSString* key = [s substringWithRange: (NSRange){.location = 0, .length = range.location}];
|
||||
NSString* value = [s substringFromIndex:range.location + 1];
|
||||
|
||||
[retval setValue:value forKey:key];
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
-(BOOL) parseHttpHeader
|
||||
{
|
||||
if (!httpHeaderNotAvailable)
|
||||
@@ -197,7 +241,6 @@
|
||||
if (!self->iceHeaderSearchComplete)
|
||||
{
|
||||
UInt8 byte;
|
||||
UInt8 bytes[4];
|
||||
UInt8 terminal1[] = { '\n', '\n' };
|
||||
UInt8 terminal2[] = { '\r', '\n', '\r', '\n' };
|
||||
|
||||
@@ -224,9 +267,7 @@
|
||||
|
||||
if (iceHeaderData.length >= sizeof(terminal1))
|
||||
{
|
||||
[iceHeaderData getBytes:&bytes[0] range:(NSRange){.location = iceHeaderData.length - sizeof(terminal1), .length = sizeof(terminal1)}];
|
||||
|
||||
if (memcmp(&terminal1[0], &bytes[0], sizeof(terminal1)) == 0)
|
||||
if (memcmp(&terminal1[0], [self->iceHeaderData bytes] + iceHeaderData.length - sizeof(terminal1), sizeof(terminal1)) == 0)
|
||||
{
|
||||
self->iceHeaderAvailable = YES;
|
||||
self->iceHeaderSearchComplete = YES;
|
||||
@@ -237,9 +278,7 @@
|
||||
|
||||
if (iceHeaderData.length >= sizeof(terminal2))
|
||||
{
|
||||
[iceHeaderData getBytes:&bytes[0] range:(NSRange){.location = iceHeaderData.length - sizeof(terminal2), .length = sizeof(terminal2)}];
|
||||
|
||||
if (memcmp(&terminal2[0], &bytes[0], sizeof(terminal2)) == 0)
|
||||
if (memcmp(&terminal2[0], [self->iceHeaderData bytes] + iceHeaderData.length - sizeof(terminal2), sizeof(terminal2)) == 0)
|
||||
{
|
||||
self->iceHeaderAvailable = YES;
|
||||
self->iceHeaderSearchComplete = YES;
|
||||
@@ -248,11 +287,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (iceHeaderData.length >=4)
|
||||
if (iceHeaderData.length >= 4)
|
||||
{
|
||||
[iceHeaderData getBytes:&bytes[0] length:4];
|
||||
|
||||
if (memcmp(bytes, "ICY", 3) != 0 && memcmp(bytes, "HTTP", 4) != 0)
|
||||
if (memcmp([self->iceHeaderData bytes], "ICY ", 4) != 0 && memcmp([self->iceHeaderData bytes], "HTTP", 4) != 0)
|
||||
{
|
||||
self->iceHeaderAvailable = NO;
|
||||
self->iceHeaderSearchComplete = YES;
|
||||
@@ -269,45 +306,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
NSCharacterSet* characterSet = [NSCharacterSet characterSetWithCharactersInString:@"\r\n"];
|
||||
NSString* fullString = [[NSString alloc] initWithData:self->iceHeaderData encoding:NSUTF8StringEncoding];
|
||||
httpHeaders = [self parseIceHeader:self->iceHeaderData];
|
||||
|
||||
NSArray* strings = [fullString componentsSeparatedByCharactersInSet:characterSet];
|
||||
|
||||
httpHeaders = [NSMutableDictionary dictionary];
|
||||
|
||||
for (NSString* s in strings)
|
||||
{
|
||||
if (s.length == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([s hasPrefix:@"ICY"])
|
||||
{
|
||||
NSArray* ss = [s componentsSeparatedByString:@" "];
|
||||
|
||||
if (ss.count >= 2)
|
||||
{
|
||||
self->httpStatusCode = [ss[1] intValue];
|
||||
}
|
||||
}
|
||||
|
||||
NSRange range = [s rangeOfString:@":"];
|
||||
|
||||
if (range.location == NSNotFound)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
NSString* key = [s substringWithRange: (NSRange){.location = 0, .length = range.location}];
|
||||
NSString* value = [s substringFromIndex:range.location + 1];
|
||||
|
||||
[httpHeaders setValue:value forKey:key];
|
||||
}
|
||||
self->iceHeaderData = nil;
|
||||
}
|
||||
|
||||
if (([httpHeaders objectForKey:@"Accepts-Ranges"] ?: [httpHeaders objectForKey:@"accepts-ranges"]) != nil)
|
||||
if (([httpHeaders objectForKey:@"Accept-Ranges"] ?: [httpHeaders objectForKey:@"accept-ranges"]) != nil)
|
||||
{
|
||||
self->supportsSeek = YES;
|
||||
}
|
||||
@@ -322,7 +326,6 @@
|
||||
}
|
||||
|
||||
NSString* contentType = [httpHeaders objectForKey:@"Content-Type"] ?: [httpHeaders objectForKey:@"content-type"] ;
|
||||
|
||||
AudioFileTypeID typeIdFromMimeType = [STKHTTPDataSource audioFileTypeHintFromMimeType:contentType];
|
||||
|
||||
if (typeIdFromMimeType != 0)
|
||||
@@ -436,6 +439,11 @@
|
||||
}
|
||||
|
||||
-(int) readIntoBuffer:(UInt8*)buffer withSize:(int)size
|
||||
{
|
||||
return [self privateReadIntoBuffer:buffer withSize:size];
|
||||
}
|
||||
|
||||
-(int) privateReadIntoBuffer:(UInt8*)buffer withSize:(int)size
|
||||
{
|
||||
if (size == 0)
|
||||
{
|
||||
@@ -458,8 +466,7 @@
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
int read = (int)CFReadStreamRead(stream, buffer, size);
|
||||
int read = [super readIntoBuffer:buffer withSize:size];
|
||||
|
||||
if (read < 0)
|
||||
{
|
||||
@@ -490,8 +497,6 @@
|
||||
return;
|
||||
}
|
||||
|
||||
self->supportsSeek = NO;
|
||||
|
||||
self->currentUrl = url;
|
||||
|
||||
if (url == nil)
|
||||
@@ -511,11 +516,12 @@
|
||||
for (NSString* key in self->requestHeaders)
|
||||
{
|
||||
NSString* value = [self->requestHeaders objectForKey:key];
|
||||
|
||||
CFHTTPMessageSetHeaderFieldValue(message, (__bridge CFStringRef)key, (__bridge CFStringRef)value);
|
||||
}
|
||||
|
||||
CFHTTPMessageSetHeaderFieldValue(message, (__bridge CFStringRef)@"Accept", (__bridge CFStringRef)@"*/*");
|
||||
CFHTTPMessageSetHeaderFieldValue(message, (__bridge CFStringRef)@"Ice-MetaData", (__bridge CFStringRef)@"0");
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Accept"), CFSTR("*/*"));
|
||||
CFHTTPMessageSetHeaderFieldValue(message, CFSTR("Ice-MetaData"), CFSTR("0"));
|
||||
|
||||
stream = CFReadStreamCreateForHTTPRequest(NULL, message);
|
||||
|
||||
@@ -540,13 +546,11 @@
|
||||
}
|
||||
|
||||
// Proxy support
|
||||
|
||||
CFDictionaryRef proxySettings = CFNetworkCopySystemProxySettings();
|
||||
CFReadStreamSetProperty(stream, kCFStreamPropertyHTTPProxy, proxySettings);
|
||||
CFRelease(proxySettings);
|
||||
|
||||
// SSL support
|
||||
|
||||
if ([self->currentUrl.scheme caseInsensitiveCompare:@"https"] == NSOrderedSame)
|
||||
{
|
||||
NSDictionary* sslSettings = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@@ -563,7 +567,6 @@
|
||||
self->httpStatusCode = 0;
|
||||
|
||||
// Open
|
||||
|
||||
if (!CFReadStreamOpen(stream))
|
||||
{
|
||||
CFRelease(stream);
|
||||
|
||||
Reference in New Issue
Block a user