Newbie needs help with NSTask and NSPipe
Newbie needs help with NSTask and NSPipe
- Subject: Newbie needs help with NSTask and NSPipe
- From: Birch Browning <email@hidden>
- Date: Thu, 15 Dec 2005 09:13:10 -0800 (PST)
I'm writing a simple app using ffmpeg to convert .vob
(MPEG2) file to mpeg4. I have ffmpeg copied to my
resources folder and am able to get the task launched
and converting the vob file. The task runs exactly for
the same length of time as a shell script that
accomplished the same result, so I'm pretty sure the
conversion is completing.
However, I'm have a difficult time getting the mpeg4
data back from the pipe and file handler and then
saved to the disk. If I convert from the command line,
I get just over 1MB back in mp4 (it's a short test
video). If I convert using the app I get about 15k.
I'm obviously either not saving all of the video, or
saving the wrong info. I'm sure it's something simple,
but I've hit a wall.
If this helps, when I run the app, sendData: get
called as does taskDataAvailable: (In fact, it gets
called 3 times, thus the checking for an existing
file), but TaskCompleted: does not get called no
matter how long it runs.
Any help greatly appreciated.
Boomer
-----
/* All Rights Reserved */
#import "AppController.h"
#import <AppKit/AppKit.h>
@implementation AppController
+ (void)initialize
{
NSMutableDictionary *defaults = [NSMutableDictionary
dictionary];
/*
* Register your app's defaults here by adding
objects to the
* dictionary, eg
*
* [defaults setObject:anObject
forKey:keyForThatObject];
*
*/
[[NSUserDefaults standardUserDefaults]
registerDefaults:defaults];
[[NSUserDefaults standardUserDefaults] synchronize];
}
- (id)init
{
if ((self = [super init]))
{
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)awakeFromNib
{
[[NSApp mainMenu] setTitle:@"GSvob2mp4"];
}
- (void)applicationDidFinishLaunching:(NSNotification
*)aNotif
{
writePath = @"/home/boomer/Movies/testfile.mp4";
NSFm = [NSFileManager defaultManager];
[self startTask];
}
- (BOOL)applicationShouldTerminate:(id)sender
{
return YES;
}
- (void)applicationWillTerminate:(NSNotification
*)aNotif
{
[self killTask];
}
- (BOOL)application:(NSApplication *)application
openFile:(NSString *)fileName
{
}
- (void)showPrefPanel:(id)sender
{
}
- (void)startTask
{
NSNotificationCenter *defaultCenter =
[NSNotificationCenter defaultCenter];
NSString *toolPath = [[NSBundle mainBundle]
pathForResource:@"ffmpeg" ofType:@""];
//TODO: get user preferences to determine
arguments
NSArray *arguments = [[NSArray alloc]
initWithObjects: @"-i",@"-", @"-b", @"380", @"-r",
@"29.97", @"-s", @"352x256", @"-f", @"mp4",
@"-vcodec", @"mpeg4", @"-aspect", @"4:3", @"-g",
@"300", @"-me", @"epzs", @"-qmin", @"3", @"-qmax",
@"9", @"-hq", @"-acodec", @"aac", @"-ab", @"96",
@"-ar", @"24000", @"-ac", @"2", @"-y", @"-", nil];
NSDictionary *defaultEnvironment = [[NSProcessInfo
processInfo] environment];
NSMutableDictionary *environment =
[[NSMutableDictionary alloc]
initWithDictionary:defaultEnvironment];
task = [[NSTask alloc] init];
[defaultCenter addObserver:self
selector:@selector(taskCompleted:)
name:NSTaskDidTerminateNotification
object:task];
[task setLaunchPath:toolPath];
[task setArguments:arguments];
[environment setObject:@"YES"
forKey:@"NSUnbufferedIO"];
outPipe = [NSPipe pipe];
taskOutput = [outPipe fileHandleForReading];
[defaultCenter addObserver:self
selector:@selector(taskDataAvailable:)
name:NSFileHandleReadCompletionNotification
object:taskOutput];
[task setStandardOutput:outPipe];
[task setStandardError:outPipe];
inPipe = [NSPipe pipe];
taskInput = [inPipe fileHandleForWriting];
[task setStandardInput:inPipe];
[task launch];
[taskOutput readInBackgroundAndNotify];
[self sendData];
[arguments release];
[environment release];
}
- (void)killTask
{
if ([task isRunning])
[task terminate];
}
- (void)TaskCompleted:(NSNotification *)notif
{
int exitCode = [[notif object] terminationStatus];
if (exitCode != 0)
NSLog(@"Error: Task exited with code %d",
exitCode);
NSLog(@"Task Completed");
[[NSNotificationCenter defaultCenter]
removeObserver:self];
}
- (void)taskDataAvailable:(NSNotification *)notif
{
NSLog(@"Task Data Available!");
NSData *incomingData;
incomingData = [[notif userInfo]
objectForKey:NSFileHandleNotificationDataItem];
NSFileHandle *mp4Out;
if ([NSFm fileExistsAtPath: writePath] == NO) {
[NSFm createFileAtPath: writePath contents: nil
attributes: nil];
mp4Out = [NSFileHandle fileHandleForWritingAtPath:
writePath];
} else {
mp4Out = [NSFileHandle
fileHandleForUpdatingAtPath: writePath];
[mp4Out seekToEndOfFile];
}
[mp4Out writeData: incomingData];
[mp4Out closeFile];
[taskOutput readInBackgroundAndNotify];
}
- (void)sendData
{
inFilePath = [NSString
stringWithString:@"/home/boomer/Movies/short.vob"];
NSLog(@"We are here - 2");
NSData *inFileData = [NSData
dataWithContentsOfFile:inFilePath];
NSLog(@"We are here - 3");
[taskInput write
Data:inFileData];
}
@end
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden