Added AudioContainer plugin and made pls and m3u loaders that use it.

CQTexperiment
vspader 2007-10-09 01:20:46 +00:00
parent 0e2da5efc7
commit 88aecc7de2
35 changed files with 1137 additions and 147 deletions

View File

@ -150,7 +150,7 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
p = [NSSavePanel savePanel];
[p setAllowedFileTypes:[playlistLoader acceptablePlaylistTypes]];
[p setAllowedFileTypes:[playlistLoader acceptableContainerTypes]];
[p beginSheetForDirectory:nil file:nil modalForWindow:mainWindow modalDelegate:self didEndSelector:@selector(savePanelDidEnd:returnCode:contextInfo:) contextInfo:NULL];
}

18
Audio/AudioContainer.h Normal file
View File

@ -0,0 +1,18 @@
//
// AudioContainer.h
// CogAudio
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
@interface AudioContainer : NSObject {
}
+ (NSArray *) urlsForContainerURL:(NSURL *)url;
@end

20
Audio/AudioContainer.m Normal file
View File

@ -0,0 +1,20 @@
//
// AudioContainer.m
// CogAudio
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "AudioContainer.h"
#import "PluginController.h"
@implementation AudioContainer
+ (NSArray *) urlsForContainerURL:(NSURL *)url
{
return [[PluginController sharedPluginController] urlsForContainerURL:url];
}
@end

View File

@ -14,13 +14,7 @@
+ (id<CogDecoder>) audioDecoderForURL:(NSURL *)url
{
NSString *ext = [[url path] pathExtension];
NSDictionary *decoders = [[PluginController sharedPluginController] decoders];
Class decoder = NSClassFromString([decoders objectForKey:[ext lowercaseString]]);
return [[[decoder alloc] init] autorelease];
return [[PluginController sharedPluginController] audioDecoderForURL:url];
}
@end

View File

@ -13,14 +13,7 @@
+ (NSDictionary *)metadataForURL:(NSURL *)url
{
NSString *ext = [[url path] pathExtension];
NSDictionary *metadataReaders = [[PluginController sharedPluginController] metadataReaders];
Class metadataReader = NSClassFromString([metadataReaders objectForKey:[ext lowercaseString]]);
return [[[[metadataReader alloc] init] autorelease] metadataForURL:url];
return [[PluginController sharedPluginController] metadataForURL:url];
}
@end

View File

@ -48,6 +48,7 @@
+ (NSArray *)fileTypes;
+ (NSArray *)schemes;
+ (NSArray *)containerTypes;
@end

View File

@ -270,16 +270,23 @@
return output;
}
+ (NSArray *)containerTypes
{
return [[[PluginController sharedPluginController] containers] allKeys];
}
+ (NSArray *)fileTypes
{
PluginController *pluginController = [PluginController sharedPluginController];
NSArray *containerTypes = [[pluginController containers] allKeys];
NSArray *decoderTypes = [[pluginController decoders] allKeys];
NSArray *metdataReaderTypes = [[pluginController metadataReaders] allKeys];
NSArray *propertiesReaderTypes = [[pluginController propertiesReaders] allKeys];
NSMutableSet *types = [NSMutableSet set];
[types addObjectsFromArray:containerTypes];
[types addObjectsFromArray:decoderTypes];
[types addObjectsFromArray:metdataReaderTypes];
[types addObjectsFromArray:propertiesReaderTypes];
@ -294,5 +301,4 @@
return [[pluginController sources] allKeys];
}
@end

View File

@ -15,22 +15,7 @@
+ (NSDictionary *)propertiesForURL:(NSURL *)url
{
NSString *ext = [[url path] pathExtension];
id<CogSource> source = [AudioSource audioSourceForURL:url];
if (![source open:url])
return nil;
NSDictionary *propertiesReaders = [[PluginController sharedPluginController] propertiesReaders];
Class propertiesReader = NSClassFromString([propertiesReaders objectForKey:[ext lowercaseString]]);
NSDictionary *properties = [propertiesReader propertiesForSource:source];
[source close];
return properties;
return [[PluginController sharedPluginController] propertiesForURL:url];
}
@end

View File

@ -13,6 +13,6 @@
@interface AudioSource : NSObject {
}
+ audioSourceForURL:(NSURL *)url;
+ (id<CogSource>) audioSourceForURL:(NSURL *)url;
@end

View File

@ -11,15 +11,9 @@
@implementation AudioSource
+ audioSourceForURL:(NSURL *)url
+ (id<CogSource>) audioSourceForURL:(NSURL *)url
{
NSString *scheme = [url scheme];
NSDictionary *sources = [[PluginController sharedPluginController] sources];
Class source = NSClassFromString([sources objectForKey:scheme]);
return [[[source alloc] init] autorelease];
return [[PluginController sharedPluginController] audioSourceForURL:url];
}
@end

View File

@ -44,6 +44,8 @@
17F94DD60B8D0F7000A34E87 /* PluginController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F94DD40B8D0F7000A34E87 /* PluginController.m */; };
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DDC0B8D101100A34E87 /* Plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7B1FEA5585E11CA2CBB /* Cocoa.framework */; };
8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */; settings = {ATTRIBUTES = (Public, ); }; };
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */; };
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EC1225D0B993BD500C5B3AD /* ConverterNode.h */; };
8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC1225E0B993BD500C5B3AD /* ConverterNode.m */; };
/* End PBXBuildFile section */
@ -103,6 +105,8 @@
32DBCF5E0370ADEE00C91783 /* CogAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogAudio_Prefix.pch; sourceTree = "<group>"; };
8DC2EF5A0486A6940098B216 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
8DC2EF5B0486A6940098B216 /* CogAudio.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CogAudio.framework; sourceTree = BUILT_PRODUCTS_DIR; };
8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioContainer.h; sourceTree = "<group>"; };
8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AudioContainer.m; sourceTree = "<group>"; };
8EC1225D0B993BD500C5B3AD /* ConverterNode.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ConverterNode.h; sourceTree = "<group>"; };
8EC1225E0B993BD500C5B3AD /* ConverterNode.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = ConverterNode.m; sourceTree = "<group>"; };
D2F7E79907B2D74100F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
@ -167,6 +171,8 @@
17F94DDC0B8D101100A34E87 /* Plugin.h */,
17D21EBB0B8BF44000D1EBDE /* AudioPlayer.h */,
17D21EBC0B8BF44000D1EBDE /* AudioPlayer.m */,
8E8D3D2D0CBAEE6E00135C1B /* AudioContainer.h */,
8E8D3D2E0CBAEE6E00135C1B /* AudioContainer.m */,
17A2D3C30B8D1D37000778C4 /* AudioDecoder.h */,
17A2D3C40B8D1D37000778C4 /* AudioDecoder.m */,
17C940210B900909008627D6 /* AudioMetadataReader.h */,
@ -305,6 +311,7 @@
17B619300B909BC300BC003F /* AudioPropertiesReader.h in Headers */,
17ADB13C0B97926D00257CA2 /* AudioSource.h in Headers */,
8EC1225F0B993BD500C5B3AD /* ConverterNode.h in Headers */,
8E8D3D2F0CBAEE6E00135C1B /* AudioContainer.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -378,6 +385,7 @@
17B619310B909BC300BC003F /* AudioPropertiesReader.m in Sources */,
17ADB13D0B97926D00257CA2 /* AudioSource.m in Sources */,
8EC122600B993BD500C5B3AD /* ConverterNode.m in Sources */,
8E8D3D300CBAEE6E00135C1B /* AudioContainer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -5,6 +5,7 @@
*/
#define kCogSource @"CogSource"
#define kCogContainer @"CogContainer"
#define kCogDecoder @"CogDecoder"
#define kCogMetadataReader @"CogMetadataReader"
#define kCogPropertiesReader @"CogPropertiesReader"
@ -28,6 +29,12 @@
- (void)close;
@end
@protocol CogContainer <NSObject>
+ (NSArray *)fileTypes; //mp3, ogg, etc
+ (NSArray *)urlsForContainerURL:(NSURL *)url;
@end
@protocol CogDecoder <NSObject>
+ (NSArray *)fileTypes; //mp3, ogg, etc
@ -43,7 +50,7 @@
@protocol CogMetadataReader <NSObject>
+ (NSArray *)fileTypes;
+ (NSDictionary *)metadataForURL;
+ (NSDictionary *)metadataForURL:(NSURL *)url;
@end
@protocol CogPropertiesReader <NSObject>
@ -51,5 +58,13 @@
+ (NSDictionary *)propertiesForSource:(id<CogSource>)source;
@end
@protocol CogPluginController <NSObject>
- (id<CogSource>) audioSourceForURL:(NSURL *)url;
- (NSArray *) urlsForContainerURL:(NSURL *)url;
- (id<CogDecoder>) audioDecoderForURL:(NSURL *)url;
- (NSDictionary *) metadataForURL:(NSURL *)url;
- (NSDictionary *) propertiesForURL:(NSURL *)url;
@end

View File

@ -2,10 +2,13 @@
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
//Singleton
@interface PluginController : NSObject
@interface PluginController : NSObject <CogPluginController>
{
NSMutableDictionary *sources;
NSMutableDictionary *containers;
NSMutableDictionary *decoders;
NSMutableDictionary *metadataReaders;
NSMutableDictionary *propertiesReaders;
@ -20,11 +23,13 @@
- (void)loadPluginsAtPath:(NSString *)path;
- (void)setupSource:(NSString *)className;
- (void)setupContainer:(NSString *)className;
- (void)setupDecoder:(NSString *)className;
- (void)setupMetadataReader:(NSString *)className;
- (void)setupPropertiesReader:(NSString *)className;
- (NSDictionary *)sources;
- (NSDictionary *)containers;
- (NSDictionary *)decoders;
- (NSDictionary *)metadataReaders;
- (NSDictionary *)propertiesReaders;

View File

@ -59,6 +59,7 @@ static PluginController *sharedPluginController = nil;
self = [super init];
if (self) {
sources = [[NSMutableDictionary alloc] init];
containers = [[NSMutableDictionary alloc] init];
decoders = [[NSMutableDictionary alloc] init];
metadataReaders = [[NSMutableDictionary alloc] init];
propertiesReaders = [[NSMutableDictionary alloc] init];
@ -105,7 +106,10 @@ static PluginController *sharedPluginController = nil;
id className;
while (className = [e nextObject]) {
id pluginType = [pluginInfo objectForKey:className];
if ([pluginType isEqualToString:kCogDecoder]) {
if ([pluginType isEqualToString:kCogContainer]) {
[self setupContainer:className];
}
else if ([pluginType isEqualToString:kCogDecoder]) {
[self setupDecoder:className];
}
else if ([pluginType isEqualToString:kCogMetadataReader]) {
@ -133,6 +137,19 @@ static PluginController *sharedPluginController = nil;
[self loadPluginsAtPath:[@"~/Library/Application Support/Cog/Plugins" stringByExpandingTildeInPath]];
}
- (void)setupContainer:(NSString *)className
{
Class container = NSClassFromString(className);
if (container && [container respondsToSelector:@selector(fileTypes)]) {
NSEnumerator *fileTypesEnum = [[container fileTypes] objectEnumerator];
id fileType;
while (fileType = [fileTypesEnum nextObject])
{
[containers setObject:className forKey:[fileType lowercaseString]];
}
}
}
- (void)setupDecoder:(NSString *)className
{
Class decoder = NSClassFromString(className);
@ -187,10 +204,11 @@ static PluginController *sharedPluginController = nil;
- (void)printPluginInfo
{
/* NSLog(@"Sources: %@", sources);
NSLog(@"Decoders: %@", decoders);
NSLog(@"Metadata Readers: %@", metadataReaders);
NSLog(@"Properties Readers: %@", propertiesReaders); */
//NSLog(@"Sources: %@", sources);
//NSLog(@"Containers: %@", containers);
//NSLog(@"Decoders: %@", decoders);
//NSLog(@"Metadata Readers: %@", metadataReaders);
//NSLog(@"Properties Readers: %@", propertiesReaders);
}
- (NSDictionary *)sources
@ -198,6 +216,11 @@ static PluginController *sharedPluginController = nil;
return sources;
}
- (NSDictionary *)containers
{
return containers;
}
- (NSDictionary *)decoders
{
return decoders;
@ -214,7 +237,60 @@ static PluginController *sharedPluginController = nil;
}
- (id<CogSource>) audioSourceForURL:(NSURL *)url
{
NSString *scheme = [url scheme];
Class source = NSClassFromString([sources objectForKey:scheme]);
return [[[source alloc] init] autorelease];
}
- (NSArray *) urlsForContainerURL:(NSURL *)url
{
NSString *ext = [[url path] pathExtension];
Class container = NSClassFromString([containers objectForKey:[ext lowercaseString]]);
return [container urlsForContainerURL:url];
}
- (id<CogDecoder>) audioDecoderForURL:(NSURL *)url
{
NSString *ext = [[url path] pathExtension];
Class decoder = NSClassFromString([decoders objectForKey:[ext lowercaseString]]);
return [[[decoder alloc] init] autorelease];
}
- (NSDictionary *)metadataForURL:(NSURL *)url
{
NSString *ext = [[url path] pathExtension];
Class metadataReader = NSClassFromString([metadataReaders objectForKey:[ext lowercaseString]]);
return [metadataReader metadataForURL:url];
}
- (NSDictionary *)propertiesForURL:(NSURL *)url
{
NSString *ext = [[url path] pathExtension];
id<CogSource> source = [self audioSourceForURL:url];
if (![source open:url])
return nil;
Class propertiesReader = NSClassFromString([propertiesReaders objectForKey:[ext lowercaseString]]);
NSDictionary *properties = [propertiesReader propertiesForSource:source];
[source close];
return properties;
}
@end

View File

@ -109,6 +109,8 @@
8E75757509F31D5A0080F1EE /* Shuffle.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E75753409F31D5A0080F1EE /* Shuffle.m */; };
8E7575BE09F31D800080F1EE /* wheel.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8E7575A609F31D800080F1EE /* wheel.icns */; };
8E7575DB09F31E930080F1EE /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8E7575D909F31E930080F1EE /* Localizable.strings */; };
8E8D40880CBB038E00135C1B /* M3u.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E8D40870CBB036600135C1B /* M3u.bundle */; };
8E8D41C80CBB0DA900135C1B /* Pls.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 8E8D41C70CBB0DA000135C1B /* Pls.bundle */; };
8E9A2E860BA78B500091081B /* SecondsFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A2E840BA78B500091081B /* SecondsFormatter.m */; };
8E9A2EDA0BA78D9D0091081B /* IndexFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A2ED80BA78D9D0091081B /* IndexFormatter.m */; };
8E9A30160BA792DC0091081B /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E9A30140BA792DC0091081B /* NSFileHandle+CreateFile.m */; };
@ -305,6 +307,34 @@
remoteGlobalIDString = 8D5B49AC048680CD000E48DA;
remoteInfo = General;
};
8E8D40860CBB036600135C1B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 8D5B49B6048680CD000E48DA /* M3u.bundle */;
remoteInfo = M3u;
};
8E8D40920CBB03AF00135C1B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 8D5B49AC048680CD000E48DA /* M3u */;
remoteInfo = M3u;
};
8E8D41C60CBB0DA000135C1B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 8D5B49B6048680CD000E48DA /* Pls.bundle */;
remoteInfo = Pls;
};
8E8D41CB0CBB0DD200135C1B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = 8D5B49AC048680CD000E48DA /* Pls */;
remoteInfo = Pls;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
@ -314,6 +344,8 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
8E8D41C80CBB0DA900135C1B /* Pls.bundle in CopyFiles */,
8E8D40880CBB038E00135C1B /* M3u.bundle in CopyFiles */,
17C809E60C3BD487005707C4 /* CoreAudio.bundle in CopyFiles */,
17C8099A0C3BD233005707C4 /* FileSource.bundle in CopyFiles */,
17C809990C3BD231005707C4 /* Flac.bundle in CopyFiles */,
@ -509,6 +541,8 @@
8E7575A609F31D800080F1EE /* wheel.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = wheel.icns; sourceTree = "<group>"; };
8E7575C809F31DCA0080F1EE /* English */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.html; name = English; path = English.lproj/Credits.html; sourceTree = "<group>"; };
8E7575DA09F31E930080F1EE /* English */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/Localizable.strings; sourceTree = "<group>"; };
8E8D40820CBB036600135C1B /* M3u.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = M3u.xcodeproj; path = Plugins/M3u/M3u.xcodeproj; sourceTree = "<group>"; };
8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Pls.xcodeproj; path = Plugins/Pls/Pls.xcodeproj; sourceTree = "<group>"; };
8E9A2E830BA78B500091081B /* SecondsFormatter.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SecondsFormatter.h; sourceTree = "<group>"; };
8E9A2E840BA78B500091081B /* SecondsFormatter.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = SecondsFormatter.m; sourceTree = "<group>"; };
8E9A2ED70BA78D9D0091081B /* IndexFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IndexFormatter.h; sourceTree = "<group>"; };
@ -757,6 +791,8 @@
17B619FF0B909ED400BC003F /* PlugIns */ = {
isa = PBXGroup;
children = (
8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */,
8E8D40820CBB036600135C1B /* M3u.xcodeproj */,
17C808C00C3BD1DD005707C4 /* WavPack.xcodeproj */,
17C808B70C3BD1D2005707C4 /* Vorbis.xcodeproj */,
17C808B00C3BD1C5005707C4 /* TagLib.xcodeproj */,
@ -1009,6 +1045,22 @@
path = Icons;
sourceTree = "<group>";
};
8E8D40830CBB036600135C1B /* Products */ = {
isa = PBXGroup;
children = (
8E8D40870CBB036600135C1B /* M3u.bundle */,
);
name = Products;
sourceTree = "<group>";
};
8E8D41C30CBB0DA000135C1B /* Products */ = {
isa = PBXGroup;
children = (
8E8D41C70CBB0DA000135C1B /* Pls.bundle */,
);
name = Products;
sourceTree = "<group>";
};
8EFFCD410AA093AF00C458A5 /* FileDrawer */ = {
isa = PBXGroup;
children = (
@ -1063,6 +1115,8 @@
17C809E50C3BD47C005707C4 /* PBXTargetDependency */,
17F5613F0C3BD4E90019975C /* PBXTargetDependency */,
17F5623B0C3BD9280019975C /* PBXTargetDependency */,
8E8D40930CBB03AF00135C1B /* PBXTargetDependency */,
8E8D41CC0CBB0DD200135C1B /* PBXTargetDependency */,
);
name = Cog;
productInstallPath = "$(HOME)/Applications";
@ -1113,6 +1167,10 @@
ProductGroup = 17C808840C3BD181005707C4 /* Products */;
ProjectRef = 17C808830C3BD181005707C4 /* HTTPSource.xcodeproj */;
},
{
ProductGroup = 8E8D40830CBB036600135C1B /* Products */;
ProjectRef = 8E8D40820CBB036600135C1B /* M3u.xcodeproj */;
},
{
ProductGroup = 17C8088D0C3BD192005707C4 /* Products */;
ProjectRef = 17C8088C0C3BD192005707C4 /* MAD.xcodeproj */;
@ -1125,6 +1183,10 @@
ProductGroup = 17C8089F0C3BD1AB005707C4 /* Products */;
ProjectRef = 17C8089E0C3BD1AB005707C4 /* Musepack.xcodeproj */;
},
{
ProductGroup = 8E8D41C30CBB0DA000135C1B /* Products */;
ProjectRef = 8E8D41C20CBB0DA000135C1B /* Pls.xcodeproj */;
},
{
ProductGroup = 17C808A80C3BD1BA005707C4 /* Products */;
ProjectRef = 17C808A70C3BD1BA005707C4 /* Shorten.xcodeproj */;
@ -1240,6 +1302,20 @@
remoteRef = 17F5622D0C3BD8FB0019975C /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
8E8D40870CBB036600135C1B /* M3u.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = M3u.bundle;
remoteRef = 8E8D40860CBB036600135C1B /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
8E8D41C70CBB0DA000135C1B /* Pls.bundle */ = {
isa = PBXReferenceProxy;
fileType = wrapper.cfbundle;
path = Pls.bundle;
remoteRef = 8E8D41C60CBB0DA000135C1B /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
@ -1417,6 +1493,16 @@
name = General;
targetProxy = 17F5623A0C3BD9280019975C /* PBXContainerItemProxy */;
};
8E8D40930CBB03AF00135C1B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = M3u;
targetProxy = 8E8D40920CBB03AF00135C1B /* PBXContainerItemProxy */;
};
8E8D41CC0CBB0DD200135C1B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Pls;
targetProxy = 8E8D41CB0CBB0DD200135C1B /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */

View File

@ -24,11 +24,6 @@ typedef enum {
- (void)addURL:(NSURL *)url;
- (void)insertURLs:(NSArray *)urls atIndex:(int)index sort:(BOOL)sort;
//load playlist auto-determines type to be either pls or m3u.
- (NSArray *)urlsFromPlaylist:(NSString *)filename;
- (NSArray *)urlsFromM3u:(NSString *)filename;
- (NSArray *)urlsFromPls:(NSString *)filename;
//save playlist, auto-determines type based on extension. Uses m3u if it cannot be determined.
- (BOOL)save:(NSString *)filename;
- (BOOL)save:(NSString *)filename asType:(PlaylistType)type;
@ -36,6 +31,6 @@ typedef enum {
- (BOOL)savePls:(NSString *)filename;
- (NSArray *)acceptableFileTypes;
- (NSArray *)acceptablePlaylistTypes;
- (NSArray *)acceptableContainerTypes;
@end

View File

@ -13,31 +13,10 @@
#import "NSFileHandle+CreateFile.h"
#import "CogAudio/AudioPlayer.h"
#import "CogAudio/AudioContainer.h"
@implementation PlaylistLoader
//load/save playlist auto-determines type to be either pls or m3u.
- (NSArray *)urlsFromPlaylist:(NSString *)filename
{
NSString *ext = [filename pathExtension];
if ([ext isEqualToString:@"m3u"])
{
return [self urlsFromM3u:filename];
}
else if ([ext isEqualToString:@"pls"])
{
return [self urlsFromPls:filename];
}
else
{
NSArray *entries = [self urlsFromPls:filename];
if (entries == nil)
return [self urlsFromM3u:filename];
return entries;
}
}
- (BOOL)save:(NSString *)filename
{
NSString *ext = [filename pathExtension];
@ -109,31 +88,6 @@
}
- (NSArray *)urlsFromM3u:(NSString *)filename
{
NSError *error = nil;
NSString *contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error];
if (error || !contents) {
NSLog(@"Could not open file...%@ %@", contents, error);
return NO;
}
NSString *entry;
NSEnumerator *e = [[contents componentsSeparatedByString:@"\n"] objectEnumerator];
NSMutableArray *entries = [NSMutableArray array];
while (entry = [[e nextObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]])
{
if ([entry hasPrefix:@"#"] || [entry isEqualToString:@""]) //Ignore extra info
continue;
//Need to add basePath, and convert to URL
[entries addObject:[self urlForPath:entry relativeTo:filename]];
}
return entries;
}
- (BOOL)saveM3u:(NSString *)filename
{
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filename createFile:YES];
@ -157,42 +111,6 @@
return YES;
}
- (NSArray *)urlsFromPls:(NSString *)filename
{
NSError *error;
NSString *contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error];
if (error || !contents) {
return nil;
}
NSString *entry;
NSEnumerator *e = [[contents componentsSeparatedByString:@"\n"] objectEnumerator];
NSMutableArray *entries = [NSMutableArray array];
while (entry = [[e nextObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]])
{
NSScanner *scanner = [[NSScanner alloc] initWithString:entry];
NSString *lhs = nil;
NSString *rhs = nil;
if (![scanner scanUpToString:@"=" intoString:&lhs] || // get LHS
![scanner scanString:@"=" intoString:nil] || // skip the =
![scanner scanUpToString:@"" intoString:&rhs] || // get RHS
![lhs isEqualToString:@"File"]) // We only want file entries
{
[scanner release];
continue;
}
//need to add basepath if its a file, and convert to URL
[entries addObject:[self urlForPath:rhs relativeTo:filename]];
[scanner release];
}
return entries;
}
- (BOOL)savePls:(NSString *)filename
{
NSFileHandle *fileHandle = [NSFileHandle fileHandleForWritingAtPath:filename createFile:YES];
@ -265,8 +183,8 @@
{
if ([url isFileURL]) {
BOOL isDir;
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory:&isDir])
{
if ([[NSFileManager defaultManager] fileExistsAtPath:[url path] isDirectory:&isDir])
{
if (isDir == YES)
{
//Get subpaths
@ -303,8 +221,10 @@
while (url = [urlEnumerator nextObject])
{
//File url
if ([[self acceptablePlaylistTypes] containsObject:[[url path] pathExtension]]) {
[allURLs addObjectsFromArray:[self urlsFromPlaylist:[url path]]];
if ([[self acceptableContainerTypes] containsObject:[[[url path] pathExtension] lowercaseString]]) {
if ([url isFileURL] ) {
[allURLs addObjectsFromArray:[AudioContainer urlsForContainerURL:url]];
}
}
else
{
@ -395,12 +315,12 @@
- (NSArray *)acceptableFileTypes
{
return [[self acceptablePlaylistTypes] arrayByAddingObjectsFromArray:[AudioPlayer fileTypes]];
return [[self acceptableContainerTypes] arrayByAddingObjectsFromArray:[AudioPlayer fileTypes]];
}
- (NSArray *)acceptablePlaylistTypes
- (NSArray *)acceptableContainerTypes
{
return [NSArray arrayWithObjects:@"m3u",@"pls",nil];
return [AudioPlayer containerTypes];
}
@end

View File

@ -306,7 +306,7 @@ void ErrorCallback(const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorS
+ (NSArray *)fileTypes
{
return [NSArray arrayWithObject:@"flac"];
return [NSArray arrayWithObjects:@"flac", @"fla", nil];
}
@end

Binary file not shown.

26
Plugins/M3u/Info.plist Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.yourcocoabundle</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>NSPrincipalClass</key>
<string>M3uPlugin</string>
</dict>
</plist>

View File

@ -0,0 +1,276 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 42;
objects = {
/* Begin PBXBuildFile section */
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
8E8D40220CBAFF3900135C1B /* M3uPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D40210CBAFF3900135C1B /* M3uPlugin.m */; };
8E8D40290CBAFF4300135C1B /* M3uContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D40280CBAFF4300135C1B /* M3uContainer.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
32DBCF630370AF2F00C91783 /* M3u_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = M3u_Prefix.pch; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* M3u.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = M3u.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
8E8D401B0CBAFEF200135C1B /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; };
8E8D40200CBAFF3900135C1B /* M3uPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = M3uPlugin.h; sourceTree = "<group>"; };
8E8D40210CBAFF3900135C1B /* M3uPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = M3uPlugin.m; sourceTree = "<group>"; };
8E8D40270CBAFF4300135C1B /* M3uContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = M3uContainer.h; sourceTree = "<group>"; };
8E8D40280CBAFF4300135C1B /* M3uContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = M3uContainer.m; sourceTree = "<group>"; };
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8D5B49B3048680CD000E48DA /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
089C166AFE841209C02AAC07 /* M3u */ = {
isa = PBXGroup;
children = (
08FB77AFFE84173DC02AAC07 /* Classes */,
32C88E010371C26100C91783 /* Other Sources */,
089C167CFE841241C02AAC07 /* Resources */,
089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
19C28FB8FE9D52D311CA2CBB /* Products */,
);
name = M3u;
sourceTree = "<group>";
};
089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */,
);
name = "Frameworks and Libraries";
sourceTree = "<group>";
};
089C167CFE841241C02AAC07 /* Resources */ = {
isa = PBXGroup;
children = (
8D5B49B7048680CD000E48DA /* Info.plist */,
089C167DFE841241C02AAC07 /* InfoPlist.strings */,
);
name = Resources;
sourceTree = "<group>";
};
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
8E8D401B0CBAFEF200135C1B /* Plugin.h */,
8E8D40200CBAFF3900135C1B /* M3uPlugin.h */,
8E8D40210CBAFF3900135C1B /* M3uPlugin.m */,
8E8D40270CBAFF4300135C1B /* M3uContainer.h */,
8E8D40280CBAFF4300135C1B /* M3uContainer.m */,
);
name = Classes;
sourceTree = "<group>";
};
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
);
name = "Linked Frameworks";
sourceTree = "<group>";
};
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
089C167FFE841241C02AAC07 /* AppKit.framework */,
D2F7E65807B2D6F200F64583 /* CoreData.framework */,
089C1672FE841209C02AAC07 /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
19C28FB8FE9D52D311CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8D5B49B6048680CD000E48DA /* M3u.bundle */,
);
name = Products;
sourceTree = "<group>";
};
32C88E010371C26100C91783 /* Other Sources */ = {
isa = PBXGroup;
children = (
32DBCF630370AF2F00C91783 /* M3u_Prefix.pch */,
);
name = "Other Sources";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8D5B49AC048680CD000E48DA /* M3u */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "M3u" */;
buildPhases = (
8D5B49AF048680CD000E48DA /* Resources */,
8D5B49B1048680CD000E48DA /* Sources */,
8D5B49B3048680CD000E48DA /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = M3u;
productInstallPath = "$(HOME)/Library/Bundles";
productName = M3u;
productReference = 8D5B49B6048680CD000E48DA /* M3u.bundle */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "M3u" */;
hasScannedForEncodings = 1;
mainGroup = 089C166AFE841209C02AAC07 /* M3u */;
projectDirPath = "";
targets = (
8D5B49AC048680CD000E48DA /* M3u */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8D5B49AF048680CD000E48DA /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8D5B49B1048680CD000E48DA /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8E8D40220CBAFF3900135C1B /* M3uPlugin.m in Sources */,
8E8D40290CBAFF4300135C1B /* M3uContainer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C167EFE841241C02AAC07 /* English */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1DEB913B08733D840010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = M3u_Prefix.pch;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(HOME)/Library/Bundles";
OBJROOT = ../../build;
PRODUCT_NAME = M3u;
SYMROOT = ../../build;
WRAPPER_EXTENSION = bundle;
ZERO_LINK = YES;
};
name = Debug;
};
1DEB913C08733D840010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
);
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = M3u_Prefix.pch;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(HOME)/Library/Bundles";
OBJROOT = ../../build;
PRODUCT_NAME = M3u;
SYMROOT = ../../build;
WRAPPER_EXTENSION = bundle;
ZERO_LINK = NO;
};
name = Release;
};
1DEB913F08733D840010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
name = Debug;
};
1DEB914008733D840010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "M3u" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB913B08733D840010E9CD /* Debug */,
1DEB913C08733D840010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "M3u" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB913F08733D840010E9CD /* Debug */,
1DEB914008733D840010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 089C1669FE841209C02AAC07 /* Project object */;
}

View File

@ -0,0 +1,17 @@
//
// M3uContainer.h
// M3u
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
@interface M3uContainer : NSObject <CogContainer> {
}
@end

View File

@ -0,0 +1,70 @@
//
// M3uContainer.m
// M3u
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "M3uContainer.h"
@implementation M3uContainer
+ (NSArray *)fileTypes
{
return [NSArray arrayWithObject:@"m3u"];
}
+ (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename
{
if ([path hasPrefix:@"/"]) {
return [NSURL fileURLWithPath:path];
}
NSRange foundRange = [path rangeOfString:@"://"];
if (foundRange.location != NSNotFound)
{
return [NSURL URLWithString:path];
}
NSString *basePath = [[[baseFilename stringByStandardizingPath] stringByDeletingLastPathComponent] stringByAppendingString:@"/"];
NSMutableString *unixPath = [path mutableCopy];
//Only relative paths would have windows backslashes.
[unixPath replaceOccurrencesOfString:@"\\" withString:@"/" options:0 range:NSMakeRange(0, [unixPath length])];
return [NSURL fileURLWithPath:[basePath stringByAppendingString:[unixPath autorelease]]];
}
+ (NSArray *)urlsForContainerURL:(NSURL *)url
{
if (![url isFileURL])
return [NSArray array];
NSString *filename = [url path];
NSError *error = nil;
NSString *contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error];
if (error || !contents) {
NSLog(@"Could not open file...%@ %@", contents, error);
return NO;
}
NSString *entry;
NSEnumerator *e = [[contents componentsSeparatedByString:@"\n"] objectEnumerator];
NSMutableArray *entries = [NSMutableArray array];
while (entry = [[e nextObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]])
{
if ([entry hasPrefix:@"#"] || [entry isEqualToString:@""]) //Ignore extra info
continue;
//Need to add basePath, and convert to URL
[entries addObject:[M3uContainer urlForPath:entry relativeTo:filename]];
}
return entries;
}
@end

17
Plugins/M3u/M3uPlugin.h Normal file
View File

@ -0,0 +1,17 @@
//
// M3uPlugin.h
// M3u
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
@interface M3uPlugin : NSObject <CogPlugin> {
}
@end

20
Plugins/M3u/M3uPlugin.m Normal file
View File

@ -0,0 +1,20 @@
//
// M3uPlugin.m
// M3u
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "M3uPlugin.h"
#import "M3uContainer.h"
@implementation M3uPlugin
+ (NSDictionary *)pluginInfo
{
return [NSDictionary dictionaryWithObject:kCogContainer forKey:[M3uContainer className]];
}
@end

View File

@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'M3u' target in the 'M3u' project.
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

Binary file not shown.

26
Plugins/Pls/Info.plist Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleIconFile</key>
<string></string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.yourcocoabundle</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>NSPrincipalClass</key>
<string>PlsPlugin</string>
</dict>
</plist>

View File

@ -0,0 +1,273 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 42;
objects = {
/* Begin PBXBuildFile section */
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 089C167DFE841241C02AAC07 /* InfoPlist.strings */; };
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */; };
8E8D41980CBB0C9F00135C1B /* PlsPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D41970CBB0C9F00135C1B /* PlsPlugin.m */; };
8E8D41A10CBB0CA700135C1B /* PlsContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E8D41A00CBB0CA700135C1B /* PlsContainer.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
089C1672FE841209C02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = "<group>"; };
089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
32DBCF630370AF2F00C91783 /* Pls_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pls_Prefix.pch; sourceTree = "<group>"; };
8D5B49B6048680CD000E48DA /* Pls.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Pls.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
8E8D41960CBB0C9F00135C1B /* PlsPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlsPlugin.h; sourceTree = "<group>"; };
8E8D41970CBB0C9F00135C1B /* PlsPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlsPlugin.m; sourceTree = "<group>"; };
8E8D419F0CBB0CA700135C1B /* PlsContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlsContainer.h; sourceTree = "<group>"; };
8E8D41A00CBB0CA700135C1B /* PlsContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PlsContainer.m; sourceTree = "<group>"; };
8E8D41A50CBB0CBE00135C1B /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = Plugin.h; path = ../../Audio/Plugin.h; sourceTree = SOURCE_ROOT; };
D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8D5B49B3048680CD000E48DA /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8D5B49B4048680CD000E48DA /* Cocoa.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
089C166AFE841209C02AAC07 /* Pls */ = {
isa = PBXGroup;
children = (
08FB77AFFE84173DC02AAC07 /* Classes */,
32C88E010371C26100C91783 /* Other Sources */,
089C167CFE841241C02AAC07 /* Resources */,
089C1671FE841209C02AAC07 /* Frameworks and Libraries */,
19C28FB8FE9D52D311CA2CBB /* Products */,
);
name = Pls;
sourceTree = "<group>";
};
089C1671FE841209C02AAC07 /* Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */,
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */,
);
name = "Frameworks and Libraries";
sourceTree = "<group>";
};
089C167CFE841241C02AAC07 /* Resources */ = {
isa = PBXGroup;
children = (
8D5B49B7048680CD000E48DA /* Info.plist */,
089C167DFE841241C02AAC07 /* InfoPlist.strings */,
);
name = Resources;
sourceTree = "<group>";
};
08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup;
children = (
8E8D41A50CBB0CBE00135C1B /* Plugin.h */,
8E8D41960CBB0C9F00135C1B /* PlsPlugin.h */,
8E8D41970CBB0C9F00135C1B /* PlsPlugin.m */,
8E8D419F0CBB0CA700135C1B /* PlsContainer.h */,
8E8D41A00CBB0CA700135C1B /* PlsContainer.m */,
);
name = Classes;
sourceTree = "<group>";
};
1058C7ACFEA557BF11CA2CBB /* Linked Frameworks */ = {
isa = PBXGroup;
children = (
1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */,
);
name = "Linked Frameworks";
sourceTree = "<group>";
};
1058C7AEFEA557BF11CA2CBB /* Other Frameworks */ = {
isa = PBXGroup;
children = (
089C167FFE841241C02AAC07 /* AppKit.framework */,
D2F7E65807B2D6F200F64583 /* CoreData.framework */,
089C1672FE841209C02AAC07 /* Foundation.framework */,
);
name = "Other Frameworks";
sourceTree = "<group>";
};
19C28FB8FE9D52D311CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8D5B49B6048680CD000E48DA /* Pls.bundle */,
);
name = Products;
sourceTree = "<group>";
};
32C88E010371C26100C91783 /* Other Sources */ = {
isa = PBXGroup;
children = (
32DBCF630370AF2F00C91783 /* Pls_Prefix.pch */,
);
name = "Other Sources";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8D5B49AC048680CD000E48DA /* Pls */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "Pls" */;
buildPhases = (
8D5B49AF048680CD000E48DA /* Resources */,
8D5B49B1048680CD000E48DA /* Sources */,
8D5B49B3048680CD000E48DA /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Pls;
productInstallPath = "$(HOME)/Library/Bundles";
productName = Pls;
productReference = 8D5B49B6048680CD000E48DA /* Pls.bundle */;
productType = "com.apple.product-type.bundle";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
089C1669FE841209C02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Pls" */;
hasScannedForEncodings = 1;
mainGroup = 089C166AFE841209C02AAC07 /* Pls */;
projectDirPath = "";
targets = (
8D5B49AC048680CD000E48DA /* Pls */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
8D5B49AF048680CD000E48DA /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8D5B49B0048680CD000E48DA /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
8D5B49B1048680CD000E48DA /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8E8D41980CBB0C9F00135C1B /* PlsPlugin.m in Sources */,
8E8D41A10CBB0CA700135C1B /* PlsContainer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
089C167DFE841241C02AAC07 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
089C167EFE841241C02AAC07 /* English */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
1DEB913B08733D840010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Pls_Prefix.pch;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(HOME)/Library/Bundles";
PRODUCT_NAME = Pls;
SYMROOT = ../../build;
WRAPPER_EXTENSION = bundle;
ZERO_LINK = YES;
};
name = Debug;
};
1DEB913C08733D840010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
);
GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Pls_Prefix.pch;
INFOPLIST_FILE = Info.plist;
INSTALL_PATH = "$(HOME)/Library/Bundles";
PRODUCT_NAME = Pls;
SYMROOT = ../../build;
WRAPPER_EXTENSION = bundle;
};
name = Release;
};
1DEB913F08733D840010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
name = Debug;
};
1DEB914008733D840010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB913A08733D840010E9CD /* Build configuration list for PBXNativeTarget "Pls" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB913B08733D840010E9CD /* Debug */,
1DEB913C08733D840010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB913E08733D840010E9CD /* Build configuration list for PBXProject "Pls" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB913F08733D840010E9CD /* Debug */,
1DEB914008733D840010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 089C1669FE841209C02AAC07 /* Project object */;
}

View File

@ -0,0 +1,17 @@
//
// PlsContainer.h
// Pls
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
@interface PlsContainer : NSObject <CogContainer> {
}
@end

View File

@ -0,0 +1,81 @@
//
// PlsContainer.m
// Pls
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "PlsContainer.h"
@implementation PlsContainer
+ (NSArray *)fileTypes
{
return [NSArray arrayWithObject:@"pls"];
}
+ (NSURL *)urlForPath:(NSString *)path relativeTo:(NSString *)baseFilename
{
if ([path hasPrefix:@"/"]) {
return [NSURL fileURLWithPath:path];
}
NSRange foundRange = [path rangeOfString:@"://"];
if (foundRange.location != NSNotFound)
{
return [NSURL URLWithString:path];
}
NSString *basePath = [[[baseFilename stringByStandardizingPath] stringByDeletingLastPathComponent] stringByAppendingString:@"/"];
NSMutableString *unixPath = [path mutableCopy];
//Only relative paths would have windows backslashes.
[unixPath replaceOccurrencesOfString:@"\\" withString:@"/" options:0 range:NSMakeRange(0, [unixPath length])];
return [NSURL fileURLWithPath:[basePath stringByAppendingString:[unixPath autorelease]]];
}
+ (NSArray *)urlsForContainerURL:(NSURL *)url
{
if (![url isFileURL])
return [NSArray array];
NSString *filename = [url path];
NSError *error;
NSString *contents = [NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:&error];
if (error || !contents) {
return nil;
}
NSString *entry;
NSEnumerator *e = [[contents componentsSeparatedByString:@"\n"] objectEnumerator];
NSMutableArray *entries = [NSMutableArray array];
while (entry = [[e nextObject] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]])
{
NSScanner *scanner = [[NSScanner alloc] initWithString:entry];
NSString *lhs = nil;
NSString *rhs = nil;
if (![scanner scanUpToString:@"=" intoString:&lhs] || // get LHS
![scanner scanString:@"=" intoString:nil] || // skip the =
![scanner scanUpToString:@"" intoString:&rhs] || // get RHS
![lhs isEqualToString:@"File"]) // We only want file entries
{
[scanner release];
continue;
}
//need to add basepath if its a file, and convert to URL
[entries addObject:[self urlForPath:rhs relativeTo:filename]];
[scanner release];
}
return entries;
}
@end

17
Plugins/Pls/PlsPlugin.h Normal file
View File

@ -0,0 +1,17 @@
//
// PlsPlugin.h
// Pls
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "Plugin.h"
@interface PlsPlugin : NSObject <CogPlugin> {
}
@end

20
Plugins/Pls/PlsPlugin.m Normal file
View File

@ -0,0 +1,20 @@
//
// PlsPlugin.m
// Pls
//
// Created by Zaphod Beeblebrox on 10/8/07.
// Copyright 2007 __MyCompanyName__. All rights reserved.
//
#import "PlsPlugin.h"
#import "PlsContainer.h"
@implementation PlsPlugin
+ (NSDictionary *)pluginInfo
{
return [NSDictionary dictionaryWithObject:kCogContainer forKey:[PlsContainer className]];
}
@end

View File

@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'Pls' target in the 'Pls' project.
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

View File

@ -12,7 +12,7 @@
@implementation TagLibMetadataReader
- (NSDictionary *)metadataForURL:(NSURL *)url
+ (NSDictionary *)metadataForURL:(NSURL *)url
{
NSString *lArtist = @"", *lTitle = @"", *lAlbum = @"", *lGenre = @"";
int lYear = 0, lTrack = 0;