VLCStreamOutput.m 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*****************************************************************************
  2. * VLCStreamOutput.m: VLCKit.framework VLCStreamOutput implementation
  3. *****************************************************************************
  4. * Copyright (C) 2008 Pierre d'Herbemont
  5. * Copyright (C) 2008, 2014 VLC authors and VideoLAN
  6. * Copyright (C) 2012 Brendon Justin
  7. * $Id$
  8. *
  9. * Authors: Pierre d'Herbemont <pdherbemont # videolan.org>
  10. * Brendon Justin <brendonjustin # gmail.com>
  11. *
  12. * This program is free software; you can redistribute it and/or modify it
  13. * under the terms of the GNU Lesser General Public License as published by
  14. * the Free Software Foundation; either version 2.1 of the License, or
  15. * (at your option) any later version.
  16. *
  17. * This program is distributed in the hope that it will be useful,
  18. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  20. * GNU Lesser General Public License for more details.
  21. *
  22. * You should have received a copy of the GNU Lesser General Public License
  23. * along with this program; if not, write to the Free Software Foundation,
  24. * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  25. *****************************************************************************/
  26. #import "VLCStreamOutput.h"
  27. #import "VLCLibVLCBridging.h"
  28. @interface VLCStreamOutput ()
  29. {
  30. NSMutableDictionary *_options;
  31. }
  32. @end
  33. @implementation VLCStreamOutput
  34. - (instancetype)init
  35. {
  36. return [self initWithOptionDictionary:nil];
  37. }
  38. - (instancetype)initWithOptionDictionary:(NSDictionary *)dictionary
  39. {
  40. if (self = [super init])
  41. _options = [dictionary mutableCopy];
  42. return self;
  43. }
  44. - (NSString *)description
  45. {
  46. return [self representedLibVLCOptions];
  47. }
  48. + (instancetype)streamOutputWithOptionDictionary:(NSDictionary *)dictionary
  49. {
  50. return [[self alloc] initWithOptionDictionary:dictionary];
  51. }
  52. + (id)rtpBroadcastStreamOutputWithSAPAnnounce:(NSString *)announceName
  53. {
  54. return [self streamOutputWithOptionDictionary:@{
  55. @"rtpOptions" : @{
  56. @"muxer" : @"ts",
  57. @"access" : @"file",
  58. @"sdp" : @"sdp",
  59. @"sap" : @"sap",
  60. @"name" : [announceName copy],
  61. @"destination" : @"239.255.1.1"
  62. }
  63. }];
  64. }
  65. + (id)rtpBroadcastStreamOutput
  66. {
  67. return [self rtpBroadcastStreamOutputWithSAPAnnounce:@"Helloworld!"];
  68. }
  69. + (id)ipodStreamOutputWithFilePath:(NSString *)filePath
  70. {
  71. return [self streamOutputWithOptionDictionary:@{
  72. @"transcodingOptions" : @{
  73. @"videoCodec" : @"h264",
  74. @"videoBitrate" : @"1024",
  75. @"audioCodec" : @"mp3",
  76. @"audioBitrate" : @"128",
  77. @"channels" : @"2",
  78. @"width" : @"640",
  79. @"height" : @"480",
  80. @"audio-sync" : @"Yes"
  81. },
  82. @"outputOptions" : @{
  83. @"muxer" : @"mp4",
  84. @"access" : @"file",
  85. @"destination" : [[NSURL URLWithString:filePath] absoluteString]
  86. }
  87. }];
  88. }
  89. + (id)mpeg4StreamOutputWithFilePath:(NSString *)filePath
  90. {
  91. return [self streamOutputWithOptionDictionary:@{
  92. @"transcodingOptions" : @{
  93. @"videoCodec" : @"mp4v",
  94. @"videoBitrate" : @"1024",
  95. @"audioCodec" : @"mp4a",
  96. @"audioBitrate" : @"192"
  97. },
  98. @"outputOptions" : @{
  99. @"muxer" : @"mp4",
  100. @"access" : @"file",
  101. @"destination" : [filePath copy]
  102. }
  103. }];
  104. }
  105. + (instancetype)streamOutputWithFilePath:(NSString *)filePath
  106. {
  107. return [self streamOutputWithOptionDictionary:@{
  108. @"outputOptions" : @{
  109. @"muxer" : @"ps",
  110. @"access" : @"file",
  111. @"destination" : [filePath copy]
  112. }
  113. }];
  114. }
  115. + (id)mpeg2StreamOutputWithFilePath:(NSString *)filePath;
  116. {
  117. return [self streamOutputWithOptionDictionary:@{
  118. @"transcodingOptions" : @{
  119. @"videoCodec" : @"mp2v",
  120. @"videoBitrate" : @"1024",
  121. @"audioCodec" : @"mpga",
  122. @"audioBitrate" : @"128",
  123. @"audio-sync" : @"Yes"
  124. },
  125. @"outputOptions" : @{
  126. @"muxer" : @"ps",
  127. @"access" : @"file",
  128. @"destination" : [filePath copy]
  129. }
  130. }];
  131. }
  132. @end
  133. @implementation VLCStreamOutput (LibVLCBridge)
  134. - (NSString *)representedLibVLCOptions
  135. {
  136. NSString * representedOptions;
  137. NSMutableArray * subOptions = [NSMutableArray array];
  138. NSMutableArray * optionsAsArray = [NSMutableArray array];
  139. NSDictionary * transcodingOptions = _options[@"transcodingOptions"];
  140. if( transcodingOptions )
  141. {
  142. NSString * videoCodec = transcodingOptions[@"videoCodec"];
  143. NSString * audioCodec = transcodingOptions[@"audioCodec"];
  144. NSString * subtitleCodec = transcodingOptions[@"subtitleCodec"];
  145. NSString * videoBitrate = transcodingOptions[@"videoBitrate"];
  146. NSString * audioBitrate = transcodingOptions[@"audioBitrate"];
  147. NSString * channels = transcodingOptions[@"channels"];
  148. NSString * height = transcodingOptions[@"height"];
  149. NSString * canvasHeight = transcodingOptions[@"canvasHeight"];
  150. NSString * width = transcodingOptions[@"width"];
  151. NSString * audioSync = transcodingOptions[@"audioSync"];
  152. NSString * videoEncoder = transcodingOptions[@"videoEncoder"];
  153. NSString * subtitleEncoder = transcodingOptions[@"subtitleEncoder"];
  154. NSString * subtitleOverlay = transcodingOptions[@"subtitleOverlay"];
  155. if( videoEncoder ) [subOptions addObject:[NSString stringWithFormat:@"venc=%@", videoEncoder]];
  156. if( videoCodec ) [subOptions addObject:[NSString stringWithFormat:@"vcodec=%@", videoCodec]];
  157. if( videoBitrate ) [subOptions addObject:[NSString stringWithFormat:@"vb=%@", videoBitrate]];
  158. if( width ) [subOptions addObject:[NSString stringWithFormat:@"width=%@", width]];
  159. if( height ) [subOptions addObject:[NSString stringWithFormat:@"height=%@", height]];
  160. if( canvasHeight ) [subOptions addObject:[NSString stringWithFormat:@"canvas-height=%@", canvasHeight]];
  161. if( audioCodec ) [subOptions addObject:[NSString stringWithFormat:@"acodec=%@", audioCodec]];
  162. if( audioBitrate ) [subOptions addObject:[NSString stringWithFormat:@"ab=%@", audioBitrate]];
  163. if( channels ) [subOptions addObject:[NSString stringWithFormat:@"channels=%@", channels]];
  164. if( audioSync ) [subOptions addObject:@"audioSync"];
  165. if( subtitleCodec ) [subOptions addObject:[NSString stringWithFormat:@"scodec=%@", subtitleCodec]];
  166. if( subtitleEncoder ) [subOptions addObject:[NSString stringWithFormat:@"senc=%@", subtitleEncoder]];
  167. if( subtitleOverlay ) [subOptions addObject:@"soverlay"];
  168. [optionsAsArray addObject: [NSString stringWithFormat:@"#transcode{%@}", [subOptions componentsJoinedByString:@","]]];
  169. [subOptions removeAllObjects];
  170. }
  171. NSDictionary * outputOptions = _options[@"outputOptions"];
  172. if( outputOptions )
  173. {
  174. NSString * muxer = outputOptions[@"muxer"];
  175. NSString * destination = outputOptions[@"destination"];
  176. NSString * url = outputOptions[@"url"];
  177. NSString * access = outputOptions[@"access"];
  178. if( muxer ) [subOptions addObject:[NSString stringWithFormat:@"mux=%@", muxer]];
  179. if( destination ) [subOptions addObject:[NSString stringWithFormat:@"dst=\"%@\"", [destination stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]]];
  180. if( url ) [subOptions addObject:[NSString stringWithFormat:@"url=\"%@\"", [url stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]]];
  181. if( access ) [subOptions addObject:[NSString stringWithFormat:@"access=%@", access]];
  182. NSString *std = [NSString stringWithFormat:@"std{%@}", [subOptions componentsJoinedByString:@","]];
  183. if ( !transcodingOptions )
  184. std = [NSString stringWithFormat:@"#%@", std];
  185. [optionsAsArray addObject:std];
  186. [subOptions removeAllObjects];
  187. }
  188. NSDictionary * rtpOptions = _options[@"rtpOptions"];
  189. if( rtpOptions )
  190. {
  191. NSString * muxer = rtpOptions[@"muxer"];
  192. NSString * destination = rtpOptions[@"destination"];
  193. NSString * sdp = rtpOptions[@"sdp"];
  194. NSString * name = rtpOptions[@"name"];
  195. NSString * sap = rtpOptions[@"sap"];
  196. if( muxer ) [subOptions addObject:[NSString stringWithFormat:@"muxer=%@", muxer]];
  197. if( destination ) [subOptions addObject:[NSString stringWithFormat:@"dst=%@", destination]];
  198. if( sdp ) [subOptions addObject:[NSString stringWithFormat:@"sdp=%@", sdp]];
  199. if( sap ) [subOptions addObject:@"sap"];
  200. if( name ) [subOptions addObject:[NSString stringWithFormat:@"name=\"%@\"", name]];
  201. NSString *rtp = [NSString stringWithFormat:@"#rtp{%@}", [subOptions componentsJoinedByString:@","]];
  202. if ( !transcodingOptions )
  203. rtp = [NSString stringWithFormat:@"#%@", rtp];
  204. [optionsAsArray addObject:rtp];
  205. [subOptions removeAllObjects];
  206. }
  207. representedOptions = [optionsAsArray componentsJoinedByString:@":"];
  208. return representedOptions;
  209. }
  210. @end