You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
216 lines
12 KiB
216 lines
12 KiB
/*****************************************************************************
|
|
* VLCStreamOutput.m: VLCKit.framework VLCStreamOutput implementation
|
|
*****************************************************************************
|
|
* Copyright (C) 2008 Pierre d'Herbemont
|
|
* Copyright (C) 2008 the VideoLAN team
|
|
* $Id$
|
|
*
|
|
* Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
|
|
*****************************************************************************/
|
|
|
|
#import "VLCStreamOutput.h"
|
|
#import "VLCLibVLCBridging.h"
|
|
|
|
@implementation VLCStreamOutput
|
|
- (id)initWithOptionDictionary:(NSDictionary *)dictionary
|
|
{
|
|
if( self = [super init] )
|
|
{
|
|
options = [[NSMutableDictionary dictionaryWithDictionary:dictionary] retain];
|
|
}
|
|
return self;
|
|
}
|
|
- (NSString *)description
|
|
{
|
|
return [self representedLibVLCOptions];
|
|
}
|
|
+ (id)streamOutputWithOptionDictionary:(NSDictionary *)dictionary
|
|
{
|
|
return [[[self alloc] initWithOptionDictionary:dictionary] autorelease];
|
|
}
|
|
+ (id)rtpBroadcastStreamOutputWithSAPAnnounce:(NSString *)announceName
|
|
{
|
|
NSString *name = [announceName copy];
|
|
id output = [self streamOutputWithOptionDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
|
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
|
@"ts", @"muxer",
|
|
@"file", @"access",
|
|
@"sdp", @"sdp",
|
|
@"sap", @"sap",
|
|
name, @"name",
|
|
@"239.255.1.1", @"destination", nil
|
|
], @"rtpOptions",
|
|
nil
|
|
]
|
|
];
|
|
[name release];
|
|
return output;
|
|
}
|
|
|
|
+ (id)rtpBroadcastStreamOutput
|
|
{
|
|
return [self rtpBroadcastStreamOutputWithSAPAnnounce:@"Helloworld!"];
|
|
}
|
|
|
|
+ (id)ipodStreamOutputWithFilePath:(NSString *)filePath
|
|
{
|
|
return [self streamOutputWithOptionDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
|
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
|
@"h264", @"videoCodec",
|
|
@"1024", @"videoBitrate", // max by Apple: 1.5 mbps
|
|
@"mp4a", @"audioCodec",
|
|
@"128", @"audioBitrate", // max by Apple: 160 kbps
|
|
@"2", @"channels",
|
|
@"640", @"width", // max by Apple: do.
|
|
@"480", @"canvasHeight", // max by Apple: do.
|
|
@"Yes", @"audio-sync",
|
|
nil
|
|
], @"transcodingOptions",
|
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
|
@"mp4", @"muxer",
|
|
@"file", @"access",
|
|
[[filePath copy] autorelease], @"destination",
|
|
nil
|
|
], @"outputOptions",
|
|
nil
|
|
]
|
|
];
|
|
}
|
|
|
|
+ (id)mpeg4StreamOutputWithFilePath:(NSString *)filePath
|
|
{
|
|
return [self streamOutputWithOptionDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
|
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
|
@"mp4v", @"videoCodec",
|
|
@"1024", @"videoBitrate",
|
|
@"mp4a", @"audioCodec",
|
|
@"192", @"audioBitrate",
|
|
nil
|
|
], @"transcodingOptions",
|
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
|
@"mp4", @"muxer",
|
|
@"file", @"access",
|
|
[[filePath copy] autorelease], @"destination", nil
|
|
], @"outputOptions",
|
|
nil
|
|
]
|
|
];
|
|
}
|
|
|
|
+ (id)streamOutputWithFilePath:(NSString *)filePath
|
|
{
|
|
return [self streamOutputWithOptionDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
|
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
|
@"ps", @"muxer",
|
|
@"file", @"access",
|
|
[[filePath copy] autorelease], @"destination", nil
|
|
], @"outputOptions",
|
|
nil
|
|
]
|
|
];
|
|
}
|
|
|
|
+ (id)mpeg2StreamOutputWithFilePath:(NSString *)filePath;
|
|
{
|
|
return [self streamOutputWithOptionDictionary:[NSDictionary dictionaryWithObjectsAndKeys:
|
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
|
@"mp2v", @"videoCodec",
|
|
@"1024", @"videoBitrate",
|
|
@"mpga", @"audioCodec",
|
|
@"128", @"audioBitrate",
|
|
@"Yes", @"audio-sync",
|
|
nil
|
|
], @"transcodingOptions",
|
|
[NSDictionary dictionaryWithObjectsAndKeys:
|
|
@"ps", @"muxer",
|
|
@"file", @"access",
|
|
[[filePath copy] autorelease], @"destination", nil
|
|
], @"outputOptions",
|
|
nil
|
|
]
|
|
];
|
|
}
|
|
@end
|
|
|
|
@implementation VLCStreamOutput (LibVLCBridge)
|
|
- (NSString *)representedLibVLCOptions
|
|
{
|
|
NSString * representedOptions;
|
|
NSMutableArray * subOptions = [NSMutableArray array];
|
|
NSMutableArray * optionsAsArray = [NSMutableArray array];
|
|
NSDictionary * transcodingOptions = [options objectForKey:@"transcodingOptions"];
|
|
if( transcodingOptions )
|
|
{
|
|
NSString * videoCodec = [transcodingOptions objectForKey:@"videoCodec"];
|
|
NSString * audioCodec = [transcodingOptions objectForKey:@"audioCodec"];
|
|
NSString * videoBitrate = [transcodingOptions objectForKey:@"videoBitrate"];
|
|
NSString * audioBitrate = [transcodingOptions objectForKey:@"audioBitrate"];
|
|
NSString * channels = [transcodingOptions objectForKey:@"channels"];
|
|
NSString * height = [transcodingOptions objectForKey:@"height"];
|
|
NSString * canvasHeight = [transcodingOptions objectForKey:@"canvasHeight"];
|
|
NSString * width = [transcodingOptions objectForKey:@"width"];
|
|
NSString * audioSync = [transcodingOptions objectForKey:@"audioSync"];
|
|
NSString * videoEncoder = [transcodingOptions objectForKey:@"videoEncoder"];
|
|
if( videoEncoder ) [subOptions addObject:[NSString stringWithFormat:@"venc=%@", videoEncoder]];
|
|
if( videoCodec ) [subOptions addObject:[NSString stringWithFormat:@"vcodec=%@", videoCodec]];
|
|
if( videoBitrate ) [subOptions addObject:[NSString stringWithFormat:@"vb=%@", videoBitrate]];
|
|
if( width ) [subOptions addObject:[NSString stringWithFormat:@"width=%@", width]];
|
|
if( height ) [subOptions addObject:[NSString stringWithFormat:@"height=%@", height]];
|
|
if( canvasHeight ) [subOptions addObject:[NSString stringWithFormat:@"canvas-height=%@", canvasHeight]];
|
|
if( audioCodec ) [subOptions addObject:[NSString stringWithFormat:@"acodec=%@", audioCodec]];
|
|
if( audioBitrate ) [subOptions addObject:[NSString stringWithFormat:@"ab=%@", audioBitrate]];
|
|
if( channels ) [subOptions addObject:[NSString stringWithFormat:@"channels=%@", channels]];
|
|
if( audioSync ) [subOptions addObject:[NSString stringWithFormat:@"audioSync", width]];
|
|
[optionsAsArray addObject: [NSString stringWithFormat:@"#transcode{%@}", [subOptions componentsJoinedByString:@","]]];
|
|
[subOptions removeAllObjects];
|
|
}
|
|
|
|
NSDictionary * outputOptions = [options objectForKey:@"outputOptions"];
|
|
if( outputOptions )
|
|
{
|
|
NSString * muxer = [outputOptions objectForKey:@"muxer"];
|
|
NSString * destination = [outputOptions objectForKey:@"destination"];
|
|
NSString * url = [outputOptions objectForKey:@"url"];
|
|
NSString * access = [outputOptions objectForKey:@"access"];
|
|
if( muxer ) [subOptions addObject:[NSString stringWithFormat:@"mux=%@", muxer]];
|
|
if( destination ) [subOptions addObject:[NSString stringWithFormat:@"dst=\"%@\"", [destination stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]]];
|
|
if( url ) [subOptions addObject:[NSString stringWithFormat:@"url=\"%@\"", [url stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]]];
|
|
if( access ) [subOptions addObject:[NSString stringWithFormat:@"access=%@", access]];
|
|
[optionsAsArray addObject:[NSString stringWithFormat:@"#std{%@}", [subOptions componentsJoinedByString:@","]]];
|
|
[subOptions removeAllObjects];
|
|
}
|
|
|
|
NSDictionary * rtpOptions = [options objectForKey:@"rtpOptions"];
|
|
if( rtpOptions )
|
|
{
|
|
NSString * muxer = [rtpOptions objectForKey:@"muxer"];
|
|
NSString * destination = [rtpOptions objectForKey:@"destination"];
|
|
NSString * sdp = [rtpOptions objectForKey:@"sdp"];
|
|
NSString * name = [rtpOptions objectForKey:@"name"];
|
|
NSString * sap = [rtpOptions objectForKey:@"sap"];
|
|
if( muxer ) [subOptions addObject:[NSString stringWithFormat:@"muxer=%@", muxer]];
|
|
if( destination ) [subOptions addObject:[NSString stringWithFormat:@"dst=%@", destination]];
|
|
if( sdp ) [subOptions addObject:[NSString stringWithFormat:@"sdp=%@", sdp]];
|
|
if( sap ) [subOptions addObject:@"sap"];
|
|
if( name ) [subOptions addObject:[NSString stringWithFormat:@"name=\"%@\"", name]];
|
|
[optionsAsArray addObject:[NSString stringWithFormat:@"#rtp{%@}", [subOptions componentsJoinedByString:@","]]];
|
|
[subOptions removeAllObjects];
|
|
}
|
|
representedOptions = [optionsAsArray componentsJoinedByString:@":"];
|
|
return representedOptions;
|
|
}
|
|
@end
|
|
|