77//
88
99#import " HLSAssetParser.h"
10+ #import " MCSNetworkUtils.h"
1011#import " MCSError.h"
1112#import " MCSURL.h"
1213#import " NSURLRequest+MCS.h"
@@ -255,7 +256,7 @@ - (nullable NSString *)hls_findValueForAttribute:(NSString *)name startPos:(NSUI
255256 NSString *matchedName = obj.numberOfRanges == 3 ? [self substringWithRange: [obj rangeAtIndex: 1 ]] : nil ;
256257 return matchedName && [matchedName isEqualToString: name];
257258 }];
258-
259+
259260 if ( result != nil ) {
260261 NSRange valueRange = [result rangeAtIndex: 2 ];
261262 NSUInteger valuePos = valueRange.location ;
@@ -286,10 +287,19 @@ - (BOOL)hls_toBOOL {
286287
287288- (NSString *)hls_restoreOriginalUrl : (NSURL *)resourceURL {
288289 if ( [self containsString: @" ://" ] ) {
290+ // Check for localhost and device IP addresses
289291 NSString *localhost = @" http://localhost" ;
292+ NSString *deviceIP = [MCSNetworkUtils getLocalIPAddress ];
293+
290294 if ( [self hasPrefix: localhost] ) {
291295 return [NSURL URLWithString: [self substringFromIndex: localhost.length] relativeToURL: resourceURL].absoluteString ;
292296 }
297+
298+ // Also check for device IP address
299+ if (deviceIP && [self hasPrefix: [NSString stringWithFormat: @" http://%@ " , deviceIP]]) {
300+ return [NSURL URLWithString: [self substringFromIndex: (deviceIP.length + 7 )] relativeToURL: resourceURL].absoluteString ;
301+ }
302+
293303 return self;
294304 }
295305 return [NSURL URLWithString: self relativeToURL: resourceURL].absoluteString ;
@@ -327,12 +337,12 @@ + (nullable NSString *)proxyPlaylistWithAsset:(NSString *)assetName
327337 MCSErrorUserInfoReasonKey : @" Empty data or unsupported format!"
328338 }];
329339 }
330-
340+
331341 NSMutableString *_Nullable proxyPlaylist = nil ;;
332342 if ( playlist != nil ) {
333343 NSMutableArray <__kindof HLSItem *> *parsingItems = NSMutableArray .array ;
334344 proxyPlaylist = (NSMutableString *)[self parse: playlist shouldTrim: YES parsingItems: parsingItems];
335-
345+
336346 __block NSMutableArray <id <HLSVariantStream>> *_Nullable variantStreams;
337347 __block NSMutableDictionary <NSString *, HLSRenditionGroup *> *_Nullable renditionGroups;
338348 // find variant streams and renditions
@@ -363,7 +373,7 @@ + (nullable NSString *)proxyPlaylistWithAsset:(NSString *)assetName
363373 }
364374 }
365375 }];
366-
376+
367377 // selected variant stream
368378 id <HLSVariantStream> _Nullable selectedVariantStream = nil ;
369379 // selected renditions
@@ -380,7 +390,7 @@ + (nullable NSString *)proxyPlaylistWithAsset:(NSString *)assetName
380390// NSString *key = [audioGroupID stringByAppendingFormat:@"_%ld", HLSRenditionTypeAudio];
381391// HLSRenditionGroup *group = renditionGroups[key];
382392// NSParameterAssert(group != nil);
383- // selectedAudioRendition =
393+ // selectedAudioRendition =
384394// group.renditions.count > 1 ? [self selectRenditionInGroup:group originalURL:originalURL currentURL:currentURL renditionSelectionHandler:renditionSelectionHandler] :
385395// group.renditions.firstObject;
386396// }
@@ -403,7 +413,7 @@ + (nullable NSString *)proxyPlaylistWithAsset:(NSString *)assetName
403413 currentURL: currentURL
404414 renditionSelectionHandler: renditionSelectionHandler];
405415 }
406-
416+
407417 [parsingItems enumerateObjectsWithOptions: NSEnumerationReverse usingBlock: ^(__kindof HLSItem * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
408418 BOOL shouldRemove = NO ;
409419 switch (obj.itemType ) {
@@ -427,13 +437,13 @@ + (nullable NSString *)proxyPlaylistWithAsset:(NSString *)assetName
427437 break ;
428438 }
429439 }
430-
440+
431441 // remove contents
432442 if ( shouldRemove ) {
433443 [proxyPlaylist replaceCharactersInRange: NSMakeRange (obj.startPosition, obj.length) withString: @" " ];
434444 return ; // return;
435445 }
436-
446+
437447 // replace URI with proxy url
438448 NSString *URI = obj.URI ;
439449 if ( URI == nil ) return ;
@@ -456,7 +466,7 @@ + (NSString *)parse:(NSString *)playlist shouldTrim:(BOOL)shouldTrim parsingItem
456466 __block NSUInteger offset = 0 ;
457467 [lines enumerateObjectsUsingBlock: ^(NSString *line, NSUInteger idx, BOOL * _Nonnull stop) {
458468 if ( shouldTrim && trimmedPlaylist.length != 0 ) [trimmedPlaylist appendString: @" \n " ];
459-
469+
460470 // 去除行首尾的空白字符; 每一行要么是一个标签(以 #EXT 开头), 要么是一个 URI
461471 NSString *curLine = shouldTrim ? [line stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet ]] : line;
462472 // 跳过空行和注释
@@ -465,7 +475,7 @@ + (NSString *)parse:(NSString *)playlist shouldTrim:(BOOL)shouldTrim parsingItem
465475 BOOL isUri = !isTag && !isComments && curLine.length > 0 ;
466476 if ( isTag ) [self handleTag: curLine offset: offset parsingItems: parsingItems context: ctx]; // 这是一个标签行
467477 else if ( isUri ) [self handleURI: curLine offset: offset context: ctx]; // 这是一个 URI 行
468-
478+
469479 if ( shouldTrim && !isComments ) [trimmedPlaylist appendString: curLine];
470480 offset = (shouldTrim ? trimmedPlaylist.length : (offset + curLine.length )) + 1 ; // + @"\n"
471481 }];
@@ -658,7 +668,7 @@ + (NSRange)parseByteRange:(NSString *)byteRange prevEnd:(NSUInteger)previousEnd
658668 return NSMakeRange (location, length);
659669}
660670
661- + (id <HLSVariantStream>)selectVariantStreamInArray : (NSArray <id<HLSVariantStream>> *)streams
671+ + (id <HLSVariantStream>)selectVariantStreamInArray : (NSArray <id<HLSVariantStream>> *)streams
662672 originalURL : (NSURL *)originalURL
663673 currentURL : (NSURL *)currentURL
664674 variantStreamSelectionHandler : (nullable HLSVariantStreamSelectionHandler)variantStreamSelectionHandler {
@@ -685,7 +695,7 @@ + (NSRange)parseByteRange:(NSString *)byteRange prevEnd:(NSUInteger)previousEnd
685695 if ( rendition != nil ) return rendition;
686696 }
687697 }
688-
698+
689699 return [renditions mcs_firstOrNull: ^BOOL (id <HLSRendition> _Nonnull obj) {
690700 return obj.isDefault ; // select default rendition
691701 }] ?: renditions.firstObject ; // or first;
0 commit comments