All pastes #200516 Raw Edit

My Skills

public text v1 · immutable
#200516 ·published 2006-10-13 06:43 UTC
rendered paste body
#import "mediaEngine.h"
#import <QuickTime/QuickTime.h>
#import <QTKit/QTKit.h>
#import <QTKit/QTMovieView.h>
#import <QTKit/QTTime.h>
#import <Foundation/Foundation.h>
#import <Appkit/Appkit.h>
#import "appControl.h"

/// DECLARATION OF PUBLIC SCOPE VARIABLES
int actualTrack = 0;
int totalTracks;
NSArray* trackList;
NSTimer *timer=nil;
QTTime		tempTime;
QTMovie*	mainSoundEngine;
NSValue*	tTime;

@implementation mediaEngine

- (IBAction)next:(id)sender
{
	if (actualTrack < (totalTracks -1)) {
		actualTrack = actualTrack + 1;
		//[mainSoundEngine release];
		[self playBtn:nil];	
	}
}

- (IBAction)playBtn:(id)sender
{	
	[mainSoundEngine release];
	/// IF THERE IS A TIMER ALREADY RUNNING, WE DESTROY IT. SHOULD NOT BE NECESSARY, BUT I DONT KNOW YET HOW COCOA API
	/// MANAGES THAT INTERNALLY, PLUS IT CAN AVOID PROBLEMS WITH A USER CLICKING LOTS OF TIMES IN THE "PLAY" BUTTON UI.
	[timer invalidate];
	
	/// WE CREATE A TIMER TO UPDATE ALL THE INTERFACE OBJECTS EVERY 0.5 SECONDS ///
	timer = [NSTimer scheduledTimerWithTimeInterval: 0.1 target: self selector: @selector(displayUpdate:) userInfo: nil	repeats: YES];
	
	/// WE LOAD ALL THE TRACKS IN AN ARRAY
	trackList = [[NSBundle mainBundle] pathsForResourcesOfType:@"m4a" inDirectory:@""];
	totalTracks = [trackList count];
	NSString* track = [trackList objectAtIndex:actualTrack];
	/// 02-jul-2006 /// REPLACED HIGH LEVEL API QTMOVIEVIEW WITH NEW QTMOVIE LOW LEVEL API AS PER APPLE RECOMMENDATION.
	/// 100% WINDOWS CROSS-PLATFORM CODE NOW.
	mainSoundEngine = [QTMovie movieWithFile:track error:nil];
	[mainSoundEngine retain];
	[mainSoundEngine setVolume:[volumeSlider floatValue]];
	
	/// THESE FOLLOWING PARAMETERS SHOULD BE HANDLED BY A .PLIST FILE IN FUTURE VERSION.
	[songName setStringValue:[mainSoundEngine attributeForKey:@"QTMovieDisplayNameAttribute"]];
	[songArtist setStringValue:@"Insphire"];
	[songNumber setStringValue:[NSString stringWithFormat:@"Track %i of %i", (actualTrack+1), totalTracks]];
	tempTime = [mainSoundEngine duration];
	
	
	//tempTime = [mainSoundEngine decodeQTTimeForKey:@"QTMovieCurrentTimeAttribute"];
	//tempTime = [mainSoundEngine currentTime];
	//NSString* caca = [mainSoundEngine attributeForKey:@"QTMovieCurrentTimeAttribute"];
	//NSLog(caca);
	
	/// WE SEND SOME MESSAGES TO INFORM THE NOTIFICATION CENTER ABOUT PLAYER STATUS.
	/// I SHOULD IMPROVE THE MESSAGING SYSTEM IN NEW VERSIONS.
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(QTMovieDidEndNotification:) name:@"QTMovieDidEndNotification" object:mainSoundEngine];
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(QTMovieTimeDidChangeNotification:) name:@"QTMovieTimeDidChangeNotification" object:mainSoundEngine];
	[mainSoundEngine play];
	NSLog([tTime description]);
}

- (IBAction)previous:(id)sender
{
	if ( actualTrack > 0) {
		actualTrack = actualTrack - 1;
		[self playBtn:nil];
	}
	
	
}

- (IBAction)stop:(id)sender
{
	[mainSoundEngine stop];
	
	/// THE "timer = nil;" LINE IS VERY IMPORTANT! AFTER SOME RESEARCH, IT SEEMS THAT THE "INVALIDATE" METHOD TOTALLY CLEARS THE OBJECT.
	/// APPLICATION WILL CRASH WITHOUT THIS LINE!
	
	if ([timer isValid]) {
		[timer invalidate];
		timer = nil;
	}
}

- (IBAction)volumeChange:(id)sender
{	
	[mainSoundEngine setVolume:[volumeSlider floatValue]];
}
- (IBAction)exportMusic:(id)sender
{	
	/// FILE COPY AND MANAGEMENT ROUTINES. THIS IS VERY SKELETON CODE, AT THE MOMENT IS NOT CHECKING FOR FILE OR DIR EXISTENCE, ETC.
	/// WILL BE IMPROVED IN FUTURE REVISIONS.
	
	/// I NEED TO *** REMEMBER *** THAT I WANT TO ADD FILE AND AUDIO COMPRESSION ROUTINES TO THIS.
	
	NSFileManager *fileManager = [NSFileManager defaultManager];
	[fileManager createDirectoryAtPath:[NSString stringWithFormat:@"%@/Music/MediaPacks", NSHomeDirectory()] attributes:nil];
	[fileManager removeFileAtPath:[NSString stringWithFormat:@"%@/Music/MediaPacks/Insphire - Afterdark", NSHomeDirectory()] handler:nil];
	[fileManager createDirectoryAtPath:[NSString stringWithFormat:@"%@/Music/MediaPacks/Insphire - AfterDark", NSHomeDirectory()] attributes:nil];
	NSArray*	filebase = [[NSBundle mainBundle] pathsForResourcesOfType:@"m4a" inDirectory:@""];
	
	/// THESE VARIABLES ARE DECLARED UNSIGNED *** ON PURPOSE ***
	unsigned i, total = [filebase count];
	i = 0;
	total = [filebase count];
	[NSApp beginSheet:progressWindow
	   modalForWindow:[NSApp mainWindow]
		modalDelegate:nil
	   didEndSelector:nil
		  contextInfo:nil];
	[progressWindowBar setUsesThreadedAnimation:YES];
	[progressWindowBar setIndeterminate:NO];
	[progressWindowBar setMinValue:0.0];
	[progressWindowBar setMaxValue:(double)total];
	[progressWindowBar setDoubleValue:0.0];
	
	
	for (i=0; i<total; ++i) {
		[progressWindowBar display];
		NSString* path = [filebase objectAtIndex:i];
		NSString* fileName = [path lastPathComponent];
		
		///											/// *** WARNING HERE *** ///
		/// IF YOU PLAN TO TOUCH THIS FOLLOWING LINE BE REALLY CAREFUL. AN ERROR HERE CAN RESULT IN DATA DELETION FROM YOUR HD!,
		/// SINCE I DID NOT WROTE FILE COMPROBATION ROUTINES YET AND THE PROCESS WILL ***OVERWRITE*** DATA WITHOUT ASKING.
		[fileManager copyPath:path toPath:[NSString stringWithFormat:@"%@/Music/MediaPacks/Insphire - AfterDark/%@", NSHomeDirectory(), fileName] handler:nil];
		[progressWindowBar setDoubleValue:(double)(i+1)];
		NSLog(path);
		
		/// THIS LINE IS FOR VISUAL PURPOSES ONLY, IT ADD'S A 1 SECOND PAUSE BETWEEN EVERY LOOP ACTION
		/// THAT WAY IM SURE THAT THE APPLICATION DONT FEEL'S "HANG".....DIRTY, BUT WORKS. DIEGO.
		[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
	}
	
	///	LET'S CONSERVE MEMORY, WE DEALLOCATE AND DESTROY THE FILEMANAGER OBJECT, WE DONT NEED IT ANYMORE.
	[fileManager dealloc];
	[fileManager release];
	/// WE DESTROY THE "COPY PROGRESS" SHEET
	[NSApp endSheet:progressWindow];
	[progressWindow orderOut:self];
	
	/// WE DISPLAY THE "COPY OK" SHEET
	/// AT THIS MOMENT, THE APPLICATION IS NOT CHECKING FOR ERRORS IN THE FILE COPY PROGRESS.
	/// REMEMBER TO WRITE A CUSTOM CLASS FOR ALL THE APPLICATION DIALOGS, INSTEAD OF CREATING THE ALERTS MANUALLY.
	[NSApp beginSheet:copyOkWindow
	   modalForWindow:[NSApp mainWindow]
		modalDelegate:nil
	   didEndSelector:nil
		  contextInfo:nil];
}
- (IBAction)showProgressDialog:(id)sender
{	
	
}
- (IBAction)viewFiles:(id)sender
{	
	NSString*	path = [NSString stringWithFormat:@"%@/Music/MediaPacks", NSHomeDirectory()];
	[[NSWorkspace sharedWorkspace]openFile:path];
	[NSApp endSheet:copyOkWindow];
	[copyOkWindow orderOut:self];
}
- (IBAction)dismissCopyPanel:(id)sender
{	
	[NSApp endSheet:copyOkWindow];
	[copyOkWindow orderOut:self];
	
}
- (void) QTMovieDidEndNotification: (NSNotification *) aNotification
{
	/// WHEN FINISHING PLAYING THE ACTUAL TRACK, WE INSTRUCT THE MEDIA ENGINE TO GO FOR THE NEXT ONE. SIMPLE EH? :P
	[self next:nil];
}
- (void) QTMovieTimeDidChangeNotification: (NSNotification *) aNotification
{
	/// TO DO: CUSTOM ROUTINE FOR UPDATING ALL INTERFACE COMPONENTS I.E: ELAPSED TIME, PROGRESS BAR, ETC.
}
- (void) displayUpdate: (NSTimer *) timer
{	
	NSString*	timeString = QTStringFromTime([mainSoundEngine currentTime]);
	NSString*	formattedTime = [timeString substringWithRange:NSMakeRange(5,5)];
	
	///	WE UPDATE ALL THE UI ELEMENTS
	[playTime setStringValue:formattedTime];
}
+ (void)initialization
{	
	/// INITIALIZATION OF THE MAIN PLAYLIST
	/// THIS CLASS METHOD IS VERY IMPORTANT AND IS BEING CALLED FROM THE "APPENGINE" CLASS. 
	trackList = [[NSBundle mainBundle] pathsForResourcesOfType:@"m4a" inDirectory:@""];
}
@end