Add broadcasterctl
This commit is contained in:
parent
b2a8b9c965
commit
7408b1caff
5 changed files with 873 additions and 0 deletions
59
broadcasterctl/BroadcasterAdminController.h
Normal file
59
broadcasterctl/BroadcasterAdminController.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#define kDefaultBroadcasterLoc @"/Applications/QuickTime Broadcaster.app"
|
||||
#define kCantFindBroadcasterError "ERROR: No QuickTime Broadcaster at this location!\n"
|
||||
#define kCantLaunchBroacasterError "ERROR: Couldn't launch QuickTime Broadcaster!\n"
|
||||
#define kBroadcasterNotRunningError "ERROR: QuickTime Broadcaster not running!\n"
|
||||
#define kBadConfigFileError "ERROR: Bad Config File! Quitting QuickTime Broadcaster.\n"
|
||||
#define kCantKillError "ERROR: Can't quit QuickTime Broadcaster. Try running broadcasterctl as root.\n"
|
||||
|
||||
@interface BroadcasterAdminController : NSObject {
|
||||
NSString *myBroadcasterAppPath;
|
||||
id myBroadcasterProxy;
|
||||
BOOL outputXML;
|
||||
}
|
||||
|
||||
// Class methods
|
||||
+ (id)broadcasterAdminController;
|
||||
+ (void)printUsage;
|
||||
|
||||
// Commands (from broadcasterctl args)
|
||||
- (void)launchBroadcaster;
|
||||
- (void)startBroadcaster;
|
||||
- (void)stopBroadcaster;
|
||||
- (void)quitBroadcaster;
|
||||
- (void)printConfig;
|
||||
- (void)printXMLConfig;
|
||||
- (void)printPresets;
|
||||
|
||||
// Accessor methods
|
||||
- (NSString *)myBroadcasterAppPath;
|
||||
- (void)setMyBroadcasterAppPath:(NSString *)newPath;
|
||||
- (id)myBroadcasterProxy;
|
||||
|
||||
@end
|
544
broadcasterctl/BroadcasterAdminController.m
Normal file
544
broadcasterctl/BroadcasterAdminController.m
Normal file
|
@ -0,0 +1,544 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
|
||||
#import "BroadcasterAdminController.h"
|
||||
#import "BroadcasterRemoteAdmin.h"
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include "revision.h"
|
||||
|
||||
|
||||
@implementation BroadcasterAdminController
|
||||
|
||||
// Class methods
|
||||
+ (id)broadcasterAdminController
|
||||
{
|
||||
return [[[BroadcasterAdminController alloc] init] autorelease];
|
||||
}
|
||||
|
||||
+ (void)printUsage
|
||||
{
|
||||
NSString *versionString = [NSString stringWithCString:kVersionString];
|
||||
NSString *buildString = [NSString stringWithCString:kBuildString];
|
||||
NSString *usage = [NSString stringWithFormat:@"\nbroadcasterctl %@ (%@)\n\nUsage: broadcasterctl [-b broadcaster-path] [-a audiopreset] [-v videopreset] [-n networkpreset] [-t (audio|video|av)] [-r (record|norecord)] [-f settingsfile] ((config|status|presets|launch|start|stop|restart|quit)\n\n", versionString, buildString];
|
||||
|
||||
printf([usage cString]);
|
||||
}
|
||||
|
||||
- (NSArray *)otherBroadcasters
|
||||
{
|
||||
NSTask *psTask;
|
||||
NSString *psResult;
|
||||
NSPipe *pipe;
|
||||
NSFileHandle *pipeFileHandle;
|
||||
NSArray *splitResult;
|
||||
NSEnumerator *processEnumerator;
|
||||
id processLine;
|
||||
NSMutableArray *processesToKill = [NSMutableArray array];
|
||||
NSString *processID;
|
||||
NSScanner *processIDScanner;
|
||||
|
||||
psTask = [[[NSTask alloc] init] autorelease];
|
||||
[psTask setLaunchPath:@"/bin/ps"];
|
||||
[psTask setArguments:[NSArray arrayWithObject:@"awx"]];
|
||||
pipe = [NSPipe pipe];
|
||||
[psTask setStandardOutput:pipe];
|
||||
[psTask launch];
|
||||
[psTask waitUntilExit];
|
||||
pipeFileHandle = [pipe fileHandleForReading];
|
||||
psResult = [[[NSString alloc] initWithData:[pipeFileHandle readDataToEndOfFile] encoding:NSASCIIStringEncoding] autorelease];
|
||||
splitResult = [psResult componentsSeparatedByString:@"\n"];
|
||||
processEnumerator = [splitResult objectEnumerator];
|
||||
while (processLine = [processEnumerator nextObject]) {
|
||||
if ([processLine rangeOfString:@"/QuickTime Broadcaster.app"].location != NSNotFound) {
|
||||
processID = [NSString string];
|
||||
processIDScanner = [NSScanner scannerWithString:processLine];
|
||||
[processIDScanner scanUpToString:@" " intoString:&processID];
|
||||
[processesToKill addObject:processID];
|
||||
}
|
||||
}
|
||||
return [NSArray arrayWithArray:processesToKill];
|
||||
}
|
||||
|
||||
- (void)killOtherBroadcastersWithSignal:(int)signal
|
||||
{
|
||||
NSArray *otherBroadcasters = [self otherBroadcasters];
|
||||
NSEnumerator *processEnumerator = [otherBroadcasters objectEnumerator];
|
||||
id process;
|
||||
BOOL success = YES;
|
||||
|
||||
while (process = [processEnumerator nextObject]) {
|
||||
if (kill([process intValue], 1) != 0)
|
||||
success = NO;
|
||||
}
|
||||
|
||||
if (!success)
|
||||
printf(kCantKillError);
|
||||
}
|
||||
|
||||
- (NSString *)resultForArgument:(NSString *)argName foundError:(BOOL *)err
|
||||
{
|
||||
NSArray *args = [[NSProcessInfo processInfo] arguments];
|
||||
unsigned long argLoc;
|
||||
NSString *result;
|
||||
|
||||
argLoc = [args indexOfObject:argName];
|
||||
if (argLoc == NSNotFound) {
|
||||
*err = NO;
|
||||
return nil;
|
||||
}
|
||||
|
||||
argLoc++;
|
||||
|
||||
// if there are no more arguments, something is wrong
|
||||
if ([args count] <= argLoc) {
|
||||
*err = YES;
|
||||
return nil;
|
||||
}
|
||||
|
||||
result = [args objectAtIndex:argLoc];
|
||||
|
||||
// if it starts with a dash, something is wrong
|
||||
if ([result characterAtIndex:0] == '-') {
|
||||
*err = YES;
|
||||
return nil;
|
||||
}
|
||||
|
||||
// at this point, all should be fine
|
||||
*err = NO;
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSString *)fixPath:(NSString *)path
|
||||
{
|
||||
NSString *pwd = [[[NSProcessInfo processInfo] environment] objectForKey:@"PWD"];
|
||||
NSMutableArray *pathComponents = [NSMutableArray arrayWithArray:[[path stringByExpandingTildeInPath] pathComponents]];
|
||||
if (!pwd)
|
||||
return path;
|
||||
if ([path isAbsolutePath])
|
||||
return path;
|
||||
|
||||
while ([[pathComponents objectAtIndex:0] isEqualToString:@".."]) {
|
||||
[pathComponents removeObjectAtIndex:0];
|
||||
pwd = [pwd stringByDeletingLastPathComponent];
|
||||
}
|
||||
|
||||
return [pwd stringByAppendingPathComponent:[NSString pathWithComponents:pathComponents]];
|
||||
}
|
||||
|
||||
- (id)init
|
||||
{
|
||||
NSArray *args = [[NSProcessInfo processInfo] arguments];
|
||||
NSString *actionArg = [args lastObject];
|
||||
BOOL err;
|
||||
NSString *argValue;
|
||||
|
||||
self = [super init];
|
||||
|
||||
if ([args count] <= 1) {
|
||||
return nil; // bail
|
||||
}
|
||||
|
||||
// look for an app path argument
|
||||
argValue = [self resultForArgument:@"-b" foundError:&err];
|
||||
if (err)
|
||||
return nil;
|
||||
if (argValue)
|
||||
[self setMyBroadcasterAppPath:[self fixPath:argValue]];
|
||||
else
|
||||
[self setMyBroadcasterAppPath:kDefaultBroadcasterLoc];
|
||||
|
||||
// if we're not telling it to quit, launch the broadcaster if it's not running
|
||||
if ((![actionArg isEqualToString:@"quit"]) && (![self myBroadcasterProxy])) {
|
||||
if ([[self otherBroadcasters] count] > 0) {
|
||||
printf("\nCannot remotely administer the current Broadcaster.");
|
||||
printf("\nUse the 'quit' command to quit the currently running broadcaster.\n\n");
|
||||
return self;
|
||||
}
|
||||
if ([actionArg isEqualToString:@"launch"])
|
||||
[self launchBroadcaster];
|
||||
else {
|
||||
printf("\nThe broadcaster isn't running.");
|
||||
printf("\nLaunch it with the 'launch' command.\n\n");
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
||||
// config file argument
|
||||
argValue = [self resultForArgument:@"-f" foundError:&err];
|
||||
if (err)
|
||||
return nil;
|
||||
if (argValue && [self myBroadcasterProxy]) {
|
||||
[[self myBroadcasterProxy] setCurrentPresetName:nil ofType:kPresetAudio];
|
||||
[[self myBroadcasterProxy] setCurrentPresetName:nil ofType:kPresetVideo];
|
||||
[[self myBroadcasterProxy] setCurrentPresetName:nil ofType:kPresetNetwork];
|
||||
NS_DURING
|
||||
[[self myBroadcasterProxy] setBroadcastSettingsFile:[self fixPath:argValue]];
|
||||
NS_HANDLER
|
||||
printf("ERROR: Invalid settings file.\n");
|
||||
return self;
|
||||
NS_ENDHANDLER
|
||||
}
|
||||
|
||||
// audio preset argument
|
||||
argValue = [self resultForArgument:@"-a" foundError:&err];
|
||||
if (err)
|
||||
return nil;
|
||||
if (argValue && [self myBroadcasterProxy]) {
|
||||
[[self myBroadcasterProxy] setCurrentPresetName:argValue ofType:kPresetAudio];
|
||||
}
|
||||
|
||||
// video preset argument
|
||||
argValue = [self resultForArgument:@"-v" foundError:&err];
|
||||
if (err)
|
||||
return nil;
|
||||
if (argValue && [self myBroadcasterProxy]) {
|
||||
[[self myBroadcasterProxy] setCurrentPresetName:argValue ofType:kPresetVideo];
|
||||
}
|
||||
|
||||
// network preset argument
|
||||
argValue = [self resultForArgument:@"-n" foundError:&err];
|
||||
if (err)
|
||||
return nil;
|
||||
if (argValue && [self myBroadcasterProxy]) {
|
||||
[[self myBroadcasterProxy] setCurrentPresetName:argValue ofType:kPresetNetwork];
|
||||
}
|
||||
|
||||
// stream type
|
||||
argValue = [self resultForArgument:@"-t" foundError:&err];
|
||||
if (err)
|
||||
return nil;
|
||||
if (argValue && [self myBroadcasterProxy]) {
|
||||
//audio/video/av
|
||||
if ([self myBroadcasterProxy]) {
|
||||
if ([argValue isEqualToString:@"audio"]) {
|
||||
[[self myBroadcasterProxy] setStreamEnabled:YES ofType:kStreamTypeAudio];
|
||||
[[self myBroadcasterProxy] setStreamEnabled:NO ofType:kStreamTypeVideo];
|
||||
}
|
||||
else if ([argValue isEqualToString:@"video"]) {
|
||||
[[self myBroadcasterProxy] setStreamEnabled:NO ofType:kStreamTypeAudio];
|
||||
[[self myBroadcasterProxy] setStreamEnabled:YES ofType:kStreamTypeVideo];
|
||||
}
|
||||
else if ([argValue isEqualToString:@"av"]) {
|
||||
[[self myBroadcasterProxy] setStreamEnabled:YES ofType:kStreamTypeAudio];
|
||||
[[self myBroadcasterProxy] setStreamEnabled:YES ofType:kStreamTypeVideo];
|
||||
}
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
/*// recording path argument
|
||||
argValue = [self resultForArgument:@"-p" foundError:&err];
|
||||
if (err)
|
||||
return nil;
|
||||
if (argValue && [self myBroadcasterProxy]) {
|
||||
[[self myBroadcasterProxy] setRecordingPath:argValue];
|
||||
}*/
|
||||
|
||||
// recording argument
|
||||
argValue = [self resultForArgument:@"-r" foundError:&err];
|
||||
if (err)
|
||||
return nil;
|
||||
if (argValue && [self myBroadcasterProxy]) {
|
||||
if ([argValue isEqualToString:@"record"])
|
||||
[[self myBroadcasterProxy] setRecording:YES];
|
||||
else if ([argValue isEqualToString:@"norecord"])
|
||||
[[self myBroadcasterProxy] setRecording:NO];
|
||||
}
|
||||
|
||||
if ([actionArg isEqualToString:@"launch"]) {
|
||||
// no need to do anything... it'll launch on its own
|
||||
}
|
||||
else if ([actionArg isEqualToString:@"start"])
|
||||
[self startBroadcaster];
|
||||
else if ([actionArg isEqualToString:@"stop"])
|
||||
[self stopBroadcaster];
|
||||
else if ([actionArg isEqualToString:@"restart"]) {
|
||||
[self stopBroadcaster];
|
||||
[self startBroadcaster];
|
||||
}
|
||||
else if ([actionArg isEqualToString:@"quit"])
|
||||
[self quitBroadcaster];
|
||||
else if (([actionArg isEqualToString:@"config"]) || ([actionArg isEqualToString:@"status"]))
|
||||
[self printConfig];
|
||||
else if ([actionArg isEqualToString:@"xmlstatus"])
|
||||
[self printXMLConfig];
|
||||
else if ([actionArg isEqualToString:@"presets"])
|
||||
[self printPresets];
|
||||
else
|
||||
return nil;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
// Commands (from broadcasterctl args)
|
||||
|
||||
- (void)launchBroadcaster
|
||||
{
|
||||
NSString *launchPath;
|
||||
NSTask *broadcasterTask;
|
||||
|
||||
launchPath = [[self myBroadcasterAppPath] stringByAppendingPathComponent:@"Contents"];
|
||||
launchPath = [launchPath stringByAppendingPathComponent:@"MacOS"];
|
||||
launchPath = [launchPath stringByAppendingPathComponent:@"QuickTime Broadcaster"];
|
||||
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath:launchPath]) {
|
||||
printf(kCantFindBroadcasterError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(broadcasterTask = [NSTask launchedTaskWithLaunchPath:launchPath arguments:[NSArray arrayWithObject:@"-noui"]])) {
|
||||
printf(kCantLaunchBroacasterError);
|
||||
return;
|
||||
}
|
||||
|
||||
if (![broadcasterTask isRunning]) {
|
||||
printf(kCantLaunchBroacasterError);
|
||||
return;
|
||||
}
|
||||
|
||||
while (![self myBroadcasterProxy])
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
- (void)startBroadcaster
|
||||
{
|
||||
int i;
|
||||
int state;
|
||||
|
||||
[myBroadcasterProxy startBroadcast];
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
sleep(1);
|
||||
state = [[self myBroadcasterProxy] state];
|
||||
if (state == kBroadcasterStateBroadcasting)
|
||||
return;
|
||||
}
|
||||
printf(kBadConfigFileError);
|
||||
[self killOtherBroadcastersWithSignal:9];
|
||||
}
|
||||
|
||||
- (void)stopBroadcaster
|
||||
{
|
||||
if (![self myBroadcasterProxy]) {
|
||||
printf(kBroadcasterNotRunningError);
|
||||
return;
|
||||
}
|
||||
|
||||
[[self myBroadcasterProxy] stopBroadcast];
|
||||
}
|
||||
|
||||
- (void)quitBroadcaster
|
||||
{
|
||||
if ([self myBroadcasterProxy]) {
|
||||
[[self myBroadcasterProxy] quit];
|
||||
}
|
||||
[self killOtherBroadcastersWithSignal:1];
|
||||
}
|
||||
|
||||
- (void)printConfig
|
||||
{
|
||||
NSString *settingStringValue;
|
||||
|
||||
if (![self myBroadcasterProxy]) {
|
||||
printf(kBroadcasterNotRunningError);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\nCurrent State: ");
|
||||
printf([[[self myBroadcasterProxy] stateString] cString]);
|
||||
|
||||
if (settingStringValue = [[self myBroadcasterProxy] broadcastSettingsFile]) {
|
||||
printf("\nBroadcast Settings File: ");
|
||||
printf([settingStringValue cString]);
|
||||
}
|
||||
|
||||
printf("\nAudio Stream: ");
|
||||
if ([[self myBroadcasterProxy] streamEnabled:kStreamTypeAudio])
|
||||
printf("Enabled");
|
||||
else
|
||||
printf("Disabled");
|
||||
|
||||
printf("\nVideo Stream: ");
|
||||
if ([[self myBroadcasterProxy] streamEnabled:kStreamTypeVideo])
|
||||
printf("Enabled");
|
||||
else
|
||||
printf("Disabled");
|
||||
|
||||
printf("\n\nCurrently Selected Presets:");
|
||||
printf("\n Audio: ");
|
||||
if (settingStringValue = [[self myBroadcasterProxy] currentPresetName:kPresetAudio])
|
||||
printf([settingStringValue cString]);
|
||||
else
|
||||
printf("(none)");
|
||||
printf("\n Video: ");
|
||||
if (settingStringValue = [[self myBroadcasterProxy] currentPresetName:kPresetVideo])
|
||||
printf([settingStringValue cString]);
|
||||
else
|
||||
printf("(none)");
|
||||
printf("\n Network: ");
|
||||
if (settingStringValue = [[self myBroadcasterProxy] currentPresetName:kPresetNetwork])
|
||||
printf([settingStringValue cString]);
|
||||
else
|
||||
printf("(none)");
|
||||
|
||||
if ([[self myBroadcasterProxy] recording]) {
|
||||
printf("\n\nRecording to ");
|
||||
settingStringValue = [[self myBroadcasterProxy] recordingPath];
|
||||
if (settingStringValue) {
|
||||
printf([settingStringValue cString]);
|
||||
}
|
||||
else
|
||||
printf("(default loc)");
|
||||
}
|
||||
else {
|
||||
printf("\n\nNot Recording");
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
}
|
||||
|
||||
- (void)printXMLConfig
|
||||
{
|
||||
NSMutableDictionary *printDict = [NSMutableDictionary dictionary];
|
||||
NSString *settingStringValue;
|
||||
NSMutableDictionary *currentPresets = [NSMutableDictionary dictionary];
|
||||
NSMutableDictionary *presetDict = [NSMutableDictionary dictionary];
|
||||
NSData *plistData;
|
||||
|
||||
if (![self myBroadcasterProxy]) {
|
||||
[printDict setObject:[NSString stringWithCString:kBroadcasterNotRunningError] forKey:@"error"];
|
||||
printf([[printDict description] cString]);
|
||||
return;
|
||||
}
|
||||
|
||||
// state and settings file
|
||||
[printDict setObject:[[self myBroadcasterProxy] stateString] forKey:@"stateString"];
|
||||
if (!(settingStringValue = [[self myBroadcasterProxy] broadcastSettingsFile]))
|
||||
settingStringValue = @"";
|
||||
[printDict setObject:settingStringValue forKey:@"broadcastSettingsFile"];
|
||||
|
||||
// currently selected presets
|
||||
if (!(settingStringValue = [[self myBroadcasterProxy] currentPresetName:kPresetAudio]))
|
||||
settingStringValue = @"";
|
||||
[currentPresets setObject:settingStringValue forKey:@"audio"];
|
||||
if (!(settingStringValue = [[self myBroadcasterProxy] currentPresetName:kPresetVideo]))
|
||||
settingStringValue = @"";
|
||||
[currentPresets setObject:settingStringValue forKey:@"video"];
|
||||
if (!(settingStringValue = [[self myBroadcasterProxy] currentPresetName:kPresetNetwork]))
|
||||
settingStringValue = @"";
|
||||
[currentPresets setObject:settingStringValue forKey:@"network"];
|
||||
[printDict setObject:currentPresets forKey:@"selectedPresets"];
|
||||
|
||||
// recording options
|
||||
[printDict setObject:[NSNumber numberWithBool:[[self myBroadcasterProxy] recording]] forKey:@"recording"];
|
||||
[printDict setObject:[[self myBroadcasterProxy] recordingPath] forKey:@"recordingPath"];
|
||||
|
||||
// all presets
|
||||
[presetDict setObject:[[self myBroadcasterProxy] presetNameList:kPresetAudio] forKey:@"audio"];
|
||||
[presetDict setObject:[[self myBroadcasterProxy] presetNameList:kPresetVideo] forKey:@"video"];
|
||||
[presetDict setObject:[[self myBroadcasterProxy] presetNameList:kPresetNetwork] forKey:@"network"];
|
||||
[printDict setObject:presetDict forKey:@"allPresets"];
|
||||
|
||||
// print the dictionary
|
||||
plistData = (NSData *)CFPropertyListCreateXMLData(NULL, printDict);
|
||||
|
||||
printf([[[NSString alloc] initWithData:plistData encoding:NSUTF8StringEncoding] cString]);
|
||||
}
|
||||
|
||||
- (void)printPresets
|
||||
{
|
||||
NSArray *allPresets;
|
||||
NSEnumerator *presetEnumerator;
|
||||
id currentPreset;
|
||||
|
||||
if (![self myBroadcasterProxy]) {
|
||||
printf(kBroadcasterNotRunningError);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Audio Presets:\n");
|
||||
allPresets = [[self myBroadcasterProxy] presetNameList:kPresetAudio];
|
||||
if ([allPresets count] == 0)
|
||||
printf(" (none)\n");
|
||||
else {
|
||||
presetEnumerator = [allPresets objectEnumerator];
|
||||
while (currentPreset = [presetEnumerator nextObject]) {
|
||||
printf(" ");
|
||||
printf([currentPreset cString]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("Video Presets:\n");
|
||||
allPresets = [[self myBroadcasterProxy] presetNameList:kPresetVideo];
|
||||
if ([allPresets count] == 0)
|
||||
printf(" (none)\n");
|
||||
else {
|
||||
presetEnumerator = [allPresets objectEnumerator];
|
||||
while (currentPreset = [presetEnumerator nextObject]) {
|
||||
printf(" ");
|
||||
printf([currentPreset cString]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("Network Presets:\n");
|
||||
allPresets = [[self myBroadcasterProxy] presetNameList:kPresetNetwork];
|
||||
if ([allPresets count] == 0)
|
||||
printf(" (none)\n");
|
||||
else {
|
||||
presetEnumerator = [allPresets objectEnumerator];
|
||||
while (currentPreset = [presetEnumerator nextObject]) {
|
||||
printf(" ");
|
||||
printf([currentPreset cString]);
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Accessor methods
|
||||
|
||||
- (NSString *)myBroadcasterAppPath
|
||||
{
|
||||
return myBroadcasterAppPath;
|
||||
}
|
||||
|
||||
- (void)setMyBroadcasterAppPath:(NSString *)newPath
|
||||
{
|
||||
[newPath retain];
|
||||
if (myBroadcasterAppPath)
|
||||
[myBroadcasterAppPath release];
|
||||
myBroadcasterAppPath = newPath;
|
||||
}
|
||||
|
||||
- (id)myBroadcasterProxy
|
||||
{
|
||||
if (!myBroadcasterProxy) {
|
||||
myBroadcasterProxy = [[NSConnection rootProxyForConnectionWithRegisteredName:kBroadcasterRemoteAdmin host:nil] retain];
|
||||
}
|
||||
return myBroadcasterProxy;
|
||||
}
|
||||
|
||||
@end
|
106
broadcasterctl/BroadcasterRemoteAdmin.h
Executable file
106
broadcasterctl/BroadcasterRemoteAdmin.h
Executable file
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
File: BroadcasterRemoteAdmin.h
|
||||
Description: This file contains the BroadcastController protocol. This protocol is
|
||||
used to communicate with QuickTime Broadcaster.
|
||||
|
||||
*/
|
||||
|
||||
// Mach nameserver name
|
||||
#define kBroadcasterRemoteAdmin @"QuickTimeBroadcasterRemoteAdmin"
|
||||
|
||||
// stream types
|
||||
#define kStreamTypeAudio @"audio"
|
||||
#define kStreamTypeVideo @"video"
|
||||
|
||||
// distributed notifications
|
||||
#define kBroadcastQuitNotification @"BroadcastQuitNotification"
|
||||
#define kBroadcastLaunchedNotification @"BraodcastLaunchedNotification"
|
||||
|
||||
// settings
|
||||
enum
|
||||
{
|
||||
kSettingsAudio = 0,
|
||||
kSettingsVideo,
|
||||
kSettingsNetwork
|
||||
};
|
||||
|
||||
// preset types
|
||||
enum
|
||||
{
|
||||
kPresetAudio = 0,
|
||||
kPresetVideo,
|
||||
kPresetNetwork
|
||||
};
|
||||
|
||||
// broadcast state
|
||||
enum
|
||||
{
|
||||
kBroadcasterStateSetup = 0,
|
||||
kBroadcasterStateStartingBroadcast,
|
||||
kBroadcasterStatePrerolling,
|
||||
kBroadcasterStateBroadcasting,
|
||||
kBroadcasterStateStoppingBroadcast
|
||||
};
|
||||
|
||||
// stats
|
||||
#define kBroadcastStatisticCPULoad 'cpul'
|
||||
#define kBroadcastStatisticNumberOfUsersConnected 'nviw'
|
||||
#define kBroadcastStatisticDataRate 'drto'
|
||||
#define kBroadcastStatisticFrameRate 'fps '
|
||||
|
||||
// the protocol used for remote admin (version 1)
|
||||
@protocol BroadcastControllerProtocolVersion1
|
||||
|
||||
// getters
|
||||
- (NSString *)currentPresetName:(short)thePresetType;
|
||||
- (BOOL)recording;
|
||||
- (NSString *)recordingPath;
|
||||
- (NSString *)recordingFileName;
|
||||
- (NSArray *)presetNameList:(short)thePresetType;
|
||||
- (NSString *)broadcastSettingsFile;
|
||||
- (NSString *)stat:(OSType)theType forStreamType:(NSString *)theStreamType;
|
||||
- (UInt32)state;
|
||||
- (NSString *)stateString;
|
||||
- (BOOL)streamEnabled:(NSString *)theStreamType;
|
||||
- (BOOL)streamActive:(NSString *)theStreamType;
|
||||
- (ComponentResult)broadcastError;
|
||||
- (NSString *)broadcastErrorString;
|
||||
|
||||
// setters
|
||||
- (void)setCurrentPresetName:(NSString *)thePresetName ofType:(short)thePresetType;
|
||||
- (void)setRecording:(BOOL)recordOn;
|
||||
- (void)setRecordingPath:(NSString *)thePath;
|
||||
- (void)setRecordingFileName:(NSString *)theFileName;
|
||||
- (void)setBroadcastSettingsFile:(NSString *)thePath;
|
||||
- (void)setStreamEnabled:(BOOL)enable ofType:(NSString *)theStreamType;
|
||||
|
||||
// methods
|
||||
- (void)startBroadcast;
|
||||
- (void)stopBroadcast;
|
||||
- (void)quit;
|
||||
|
||||
@end
|
125
broadcasterctl/broadcasterctl.1
Normal file
125
broadcasterctl/broadcasterctl.1
Normal file
|
@ -0,0 +1,125 @@
|
|||
.TH BROADCASTERCTL 1 "August 16, 2002" "Apple Computer, Inc."
|
||||
.SH NAME
|
||||
broadcasterctl \- controller for the QuickTime Broadcaster
|
||||
.SH SYNOPSIS
|
||||
.B broadcasterctl
|
||||
[-b broadcaster-path] [-a audiopreset] [-v videopreset] [-n networkpreset]
|
||||
[-t (audio|video|av)] [-r (record|norecord)] [-p recording-path] [-f settingsfile]
|
||||
(config|status|presets|launch|start|stop|restart|quit)
|
||||
.SH DESCRIPTION
|
||||
.I broadcasterctl
|
||||
is a command line tool for controlling the
|
||||
.I QuickTime Broadcaster
|
||||
application. Using
|
||||
.I broadcasterctl
|
||||
you can configure, launch, start, and stop a
|
||||
.SM QuickTime
|
||||
streaming broadcast generated by the
|
||||
.SM MacOS X
|
||||
.I QuickTime Broadcaster
|
||||
application.
|
||||
.PP
|
||||
The
|
||||
.I QuickTime Broadcaster
|
||||
application must be accessable on the local host on which the terminal session is exectuting in order to
|
||||
communicate with that application. (i.e. It will not control a network remote copy of the
|
||||
application.)
|
||||
.SH OPTIONS
|
||||
.PP
|
||||
The following command line options can be invoked with
|
||||
.I broadcasterctl:
|
||||
.TP
|
||||
.B config
|
||||
Sets the configuration of the
|
||||
.I QuickTime Broadcaster
|
||||
application to be that of the currently specified settings file.
|
||||
.TP
|
||||
.B status
|
||||
Returns the current status
|
||||
.I QuickTime Broadcaster
|
||||
application.
|
||||
.TP
|
||||
.B presets
|
||||
Sets the presets of the
|
||||
.I QuickTime Broadcaster
|
||||
application to be that of the currently specified preset values.
|
||||
.TP
|
||||
.B launch
|
||||
Launches the
|
||||
.I QuickTime Broadcaster
|
||||
application.
|
||||
.TP
|
||||
.B start
|
||||
Tells the
|
||||
.I QuickTime Broadcaster
|
||||
application to begin the broadcast.
|
||||
.TP
|
||||
.B stop
|
||||
Tells the
|
||||
.I QuickTime Broadcaster
|
||||
application to stop the broadcast.
|
||||
.TP
|
||||
.B restart
|
||||
Tells the
|
||||
.I QuickTime Broadcaster
|
||||
application to restart the broadcast.
|
||||
.TP
|
||||
.B quit
|
||||
Causes the
|
||||
.I QuickTime Broadcaster
|
||||
application to quit.
|
||||
.TP
|
||||
.BI \-a " audiopreset"
|
||||
Specifies the the current audio preset configuration to be the name given in
|
||||
the
|
||||
.I audiopreset
|
||||
parameter.
|
||||
.TP
|
||||
.BI \-b " broadcaster-path"
|
||||
Specifies the file path to the
|
||||
.I QuickTime Broadcaster
|
||||
application.
|
||||
.TP
|
||||
.BI \-f " settingsfile"
|
||||
Specifies the file path to the broadcast settings file.
|
||||
.TP
|
||||
.BI \-n " networkpreset"
|
||||
Specifies the the current network preset configuration to be the name given in
|
||||
the
|
||||
.I networkpreset
|
||||
parameter.
|
||||
.TP
|
||||
.BI \-p " recording-path"
|
||||
Specifies the file path to record the broadcast to.
|
||||
.TP
|
||||
.BI \-r " (record|norecord)"
|
||||
Controls whether or not the
|
||||
.I QuickTime Broadcaster
|
||||
will record the broadcast to a file as it is broadcasting
|
||||
the stream. Specify
|
||||
.I record
|
||||
to record the broadcast and
|
||||
.I norecord
|
||||
to do nothing. (The default is the
|
||||
.I norecord
|
||||
option.)
|
||||
.TP
|
||||
.BI \-t " (audio|video|av)"
|
||||
Specifies the type of broadcast to be originated. Specifiy
|
||||
.I audio
|
||||
for an audio-only broadcast,
|
||||
.I video
|
||||
for an video-only broadcast, or
|
||||
.I av
|
||||
for a combination audio/video broadcast.
|
||||
.TP
|
||||
.BI \-v " videopreset"
|
||||
Specifies the the current video preset configuration to be the name given in
|
||||
the
|
||||
.I videopreset
|
||||
parameter.
|
||||
.SH "SEE ALSO"
|
||||
QuickTimeStreamingServer(1), ps(1), kill(1)
|
||||
.SH LIMITATIONS
|
||||
Only one audio, video, or audio/video session can be controlled per invokation of
|
||||
.I broadcasterctl.
|
39
broadcasterctl/broadcasterctl_main.m
Normal file
39
broadcasterctl/broadcasterctl_main.m
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "BroadcasterAdminController.h"
|
||||
|
||||
int main (int argc, const char * argv[]) {
|
||||
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
|
||||
BroadcasterAdminController *mainController;
|
||||
|
||||
mainController = [BroadcasterAdminController broadcasterAdminController];
|
||||
|
||||
if (!mainController)
|
||||
[BroadcasterAdminController printUsage];
|
||||
|
||||
[pool release];
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue