瀏覽代碼

添加ijkplayer 解决iOS16 无法播放.m3u8资源

尹永奇 2 年之前
父節點
當前提交
7212e9f461

+ 2 - 2
Example/Podfile.lock

@@ -1,5 +1,5 @@
 PODS:
-  - MKRRadioManager (0.0.3)
+  - MKRRadioManager (0.0.4)
   - YYCategory (0.0.1)
 
 DEPENDENCIES:
@@ -15,7 +15,7 @@ EXTERNAL SOURCES:
     :path: "../"
 
 SPEC CHECKSUMS:
-  MKRRadioManager: 736d6a957cf11ecf269ee6f22a02e46f4fc7a8d5
+  MKRRadioManager: a4f9d412b1b917ad6071d2255c78eee328300f37
   YYCategory: d85135b05d2806c90930a5bbadfc1501396a3db9
 
 PODFILE CHECKSUM: f65396e8a7f07654404054ab9d38dc4b7b6f8818

+ 2 - 2
Example/Pods/Local Podspecs/MKRRadioManager.podspec.json

@@ -1,6 +1,6 @@
 {
   "name": "MKRRadioManager",
-  "version": "0.0.3",
+  "version": "0.0.4",
   "summary": "A short description of MKRRadioManager.",
   "description": "TODO: Add long description of the pod here.",
   "homepage": "http://60.205.190.38:9000/iOS/MKRRadioManager.git",
@@ -13,7 +13,7 @@
   },
   "source": {
     "git": "http://60.205.190.38:9000/iOS/MKRRadioManager.git",
-    "tag": "0.0.3"
+    "tag": "0.0.4"
   },
   "platforms": {
     "ios": "8.0"

+ 2 - 2
Example/Pods/Manifest.lock

@@ -1,5 +1,5 @@
 PODS:
-  - MKRRadioManager (0.0.3)
+  - MKRRadioManager (0.0.4)
   - YYCategory (0.0.1)
 
 DEPENDENCIES:
@@ -15,7 +15,7 @@ EXTERNAL SOURCES:
     :path: "../"
 
 SPEC CHECKSUMS:
-  MKRRadioManager: 736d6a957cf11ecf269ee6f22a02e46f4fc7a8d5
+  MKRRadioManager: a4f9d412b1b917ad6071d2255c78eee328300f37
   YYCategory: d85135b05d2806c90930a5bbadfc1501396a3db9
 
 PODFILE CHECKSUM: f65396e8a7f07654404054ab9d38dc4b7b6f8818

+ 1 - 1
MKRRadioManager.podspec

@@ -8,7 +8,7 @@
 
 Pod::Spec.new do |s|
   s.name             = 'MKRRadioManager'
-  s.version          = '0.0.3'
+  s.version          = '0.0.4'
   s.summary          = 'A short description of MKRRadioManager.'
 
 # This description is used to generate tags and improve search results.

+ 216 - 23
MKRRadioManager/Classes/MKRRadioManager/MKRAVPlayer/MKRAVPlayer.m

@@ -8,6 +8,7 @@
 
 #import "MKRAVPlayer.h"
 #import <AVFoundation/AVFoundation.h>
+#import <IJKMediaFramework/IJKMediaFramework.h>
 
 inline static bool isFloatZero(float value)
 {
@@ -36,6 +37,9 @@ static void * PlayerStatusObservationContext = &PlayerStatusObservationContext;
 @property (nonatomic, assign) NSTimeInterval seekTime;//快进或者快退的目标时间
 @property (nonatomic, strong) NSMutableArray *resourcePlayList;//MKRRadioResorce播放列表
 @property (nonatomic, assign) BOOL initByUrlPlayList;//是字符串播放列表
+@property (nonatomic, strong) id<IJKMediaPlayback> ijkPlayer;
+@property (nonatomic, assign) BOOL isIjkPlayerMode;
+@property (nonatomic, assign) BOOL isInstallIjkObservers;
 @end
 
 @implementation MKRAVPlayer
@@ -148,16 +152,32 @@ NSURL * MKRUrlWithString(NSString *string){
         [self preparePlay];
     }else{
         if (self.state == MKRAVPlayerStateStopped || self.state == MKRAVPlayerStatePause) {
-            [self.player play];
+            if (self.isIjkPlayerMode){
+                [self.ijkPlayer prepareToPlay];
+                [self.ijkPlayer play];
+            }else{
+                [self.player play];
+            }
             self.state = MKRAVPlayerStatePlaying;
         }else if (self.state == MKRAVPlayerStateBuffering){
-            [self.player play];
+            if (self.isIjkPlayerMode){
+                [self.ijkPlayer prepareToPlay];
+                [self.ijkPlayer play];
+            }else{
+                [self.player play];
+            }
             self.state = MKRAVPlayerStatePlaying;
         }else if (self.state == MKRAVPlayerStatePlaying){
-            if (self.player && !self.player.rate) {
-                [self.player play];
-                self.state = MKRAVPlayerStatePlaying;
+            if (self.isIjkPlayerMode && self.ijkPlayer && !self.player.rate){
+                [self.ijkPlayer prepareToPlay];
+                [self.ijkPlayer play];
+            }else{
+                if (self.player && !self.player.rate) {
+                    [self.player play];
+                }
             }
+            self.state = MKRAVPlayerStatePlaying;
+            
         }else if (self.state == MKRAVPlayerStateFinished){
 //            NSLog(@"播放完成");
         }
@@ -250,18 +270,32 @@ NSURL * MKRUrlWithString(NSString *string){
 }
 
 - (void)pause{
-    [self.player pause];
+    if (self.isIjkPlayerMode){
+        [self.ijkPlayer pause];
+    }else{
+        [self.player pause];
+    }
     if (self.state == MKRAVPlayerStatePlaying) {
         self.state = MKRAVPlayerStatePause;
     }
 }
 
 - (void)replayCurrentResource{
-    [self resetPlayer];
+    if (self.isIjkPlayerMode){
+        [self destroyIjkPlayer];
+    }else{
+        [self resetPlayer];
+    }
     [self playAtIndex:self.currentIndex];
 }
 
 - (void)resetPlayer{
+    if (self.isIjkPlayerMode){
+        [self destroyIjkPlayer];
+    }
+    if (!self.player){
+        return;
+    }
     if ([self.delegate respondsToSelector:@selector(willChangePlayResouce:)]) {
         [self.delegate willChangePlayResouce:self.currentResource];
     }
@@ -316,23 +350,34 @@ NSURL * MKRUrlWithString(NSString *string){
     [self registerNotification];
     if (self.playerItem) {
         [self resetPlayer];
-        self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
+        if (@available(iOS 16.0, *) && self.currentResource.sourceType == MKRSourceTypeBroadcast) {
+            [self createIjkPlayer];
+        }else{
+            self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
+        }
+        
     }else{
-        self.playAsset = [AVURLAsset assetWithURL:self.playUrl];
-        NSArray *requestedKeys = @[@"playable"];
-        [self.playAsset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:^{
-             [self didPrepareToPlayAsset:self.playAsset withKeys:requestedKeys];
-        }];
-        self.playerItem = [AVPlayerItem playerItemWithAsset:self.playAsset];
-        self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
-        [self.player addObserver:self forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:PlayerStatusObservationContext];
-        __weak __typeof(self)weakSelf = self;
-        self.timeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(0.1*30, 30) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
-            CGFloat currentT = (CGFloat)CMTimeGetSeconds(time);
-            if (weakSelf.currentStatus) {
-                weakSelf.currentStatus.currentDuration = currentT;
-            }
-        }];
+        [self resetPlayer];
+        if (@available(iOS 16.0, *) && self.currentResource.sourceType == MKRSourceTypeBroadcast) {
+            [self createIjkPlayer];
+        }else{
+            self.isIjkPlayerMode = NO;
+            self.playAsset = [AVURLAsset assetWithURL:self.playUrl];
+            NSArray *requestedKeys = @[@"playable"];
+            [self.playAsset loadValuesAsynchronouslyForKeys:requestedKeys completionHandler:^{
+                 [self didPrepareToPlayAsset:self.playAsset withKeys:requestedKeys];
+            }];
+            self.playerItem = [AVPlayerItem playerItemWithAsset:self.playAsset];
+            self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
+            [self.player addObserver:self forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:PlayerStatusObservationContext];
+            __weak __typeof(self)weakSelf = self;
+            self.timeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(0.1*30, 30) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
+                CGFloat currentT = (CGFloat)CMTimeGetSeconds(time);
+                if (weakSelf.currentStatus) {
+                    weakSelf.currentStatus.currentDuration = currentT;
+                }
+            }];
+        }
     }
     self.isInitPlayer = YES;
     if (@available(iOS 10.0, *)) {
@@ -341,6 +386,62 @@ NSURL * MKRUrlWithString(NSString *string){
     self.state = MKRAVPlayerStateBuffering;
 }
 
+- (void)createIjkPlayer{
+    [self destroyIjkPlayer];
+    IJKFFOptions *options = [IJKFFOptions optionsByDefault];
+    self.ijkPlayer = [[IJKFFMoviePlayerController alloc] initWithContentURL:self.playUrl withOptions:options];
+    [self.ijkPlayer prepareToPlay];
+    self.isInitPlayer = YES;
+    self.isIjkPlayerMode = YES;
+    if (self.isInstallIjkObservers){
+        [self removeIjkMovieNotificationObservers];
+    }
+    [self installIjkMovieNotificationObservers];
+}
+
+- (void)destroyIjkPlayer{
+    if (self.ijkPlayer){
+        [self.ijkPlayer shutdown];
+        [self.ijkPlayer.view removeFromSuperview];
+        self.ijkPlayer = nil;
+        [self removeIjkMovieNotificationObservers];
+    }
+}
+
+-(void)installIjkMovieNotificationObservers
+{
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(loadStateDidChange:)
+                                                 name:IJKMPMoviePlayerLoadStateDidChangeNotification
+                                               object:self.ijkPlayer];
+
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(moviePlayBackDidFinish:)
+                                                 name:IJKMPMoviePlayerPlaybackDidFinishNotification
+                                               object:self.ijkPlayer];
+
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(mediaIsPreparedToPlayDidChange:)
+                                                 name:IJKMPMediaPlaybackIsPreparedToPlayDidChangeNotification
+                                               object:self.ijkPlayer];
+
+    [[NSNotificationCenter defaultCenter] addObserver:self
+                                             selector:@selector(moviePlayBackStateDidChange:)
+                                                 name:IJKMPMoviePlayerPlaybackStateDidChangeNotification
+                                               object:self.ijkPlayer];
+    self.isInstallIjkObservers = YES;
+}
+
+-(void)removeIjkMovieNotificationObservers
+{
+    [[NSNotificationCenter defaultCenter]removeObserver:self name:IJKMPMoviePlayerLoadStateDidChangeNotification object:_player];
+    [[NSNotificationCenter defaultCenter]removeObserver:self name:IJKMPMoviePlayerPlaybackDidFinishNotification object:_player];
+    [[NSNotificationCenter defaultCenter]removeObserver:self name:IJKMPMediaPlaybackIsPreparedToPlayDidChangeNotification object:_player];
+    [[NSNotificationCenter defaultCenter]removeObserver:self name:IJKMPMoviePlayerPlaybackStateDidChangeNotification object:_player];
+    self.isInstallIjkObservers = NO;
+}
+
+
 - (void)didPrepareToPlayAsset:(AVURLAsset *)asset withKeys:(NSArray *)requestedKeys{
     for (NSString *thisKey in requestedKeys) {
         NSError *error = nil;
@@ -529,6 +630,98 @@ NSURL * MKRUrlWithString(NSString *string){
     return _currentStatus;
 }
 
+- (void)loadStateDidChange:(NSNotification*)notification
+{
+    //    MPMovieLoadStateUnknown        = 0,
+    //    MPMovieLoadStatePlayable       = 1 << 0,
+    //    MPMovieLoadStatePlaythroughOK  = 1 << 1, // Playback will be automatically started in this state when shouldAutoplay is YES
+    //    MPMovieLoadStateStalled        = 1 << 2, // Playback will be automatically paused in this state, if started
+
+    IJKMPMovieLoadState loadState = self.ijkPlayer.loadState;
+
+    if ((loadState & IJKMPMovieLoadStatePlaythroughOK) != 0) {
+        NSLog(@"loadStateDidChange: IJKMPMovieLoadStatePlaythroughOK: %d\n", (int)loadState);
+        [self.ijkPlayer play];
+    } else if ((loadState & IJKMPMovieLoadStatePlayable) != 0) {
+        NSLog(@"loadStateDidChange: IJKMPMovieLoadStatePlayable: %d\n", (int)loadState);
+        [self.ijkPlayer play];
+    }else if ((loadState & IJKMPMovieLoadStateStalled) != 0) {
+        NSLog(@"loadStateDidChange: IJKMPMovieLoadStateStalled: %d\n", (int)loadState);
+        self.state = MKRAVPlayerStateBuffering;
+    } else {
+        NSLog(@"loadStateDidChange: ???: %d\n", (int)loadState);
+    }
+}
+
+- (void)moviePlayBackDidFinish:(NSNotification*)notification
+{
+    int reason = [[[notification userInfo] valueForKey:IJKMPMoviePlayerPlaybackDidFinishReasonUserInfoKey] intValue];
+
+    switch (reason)
+    {
+        case IJKMPMovieFinishReasonPlaybackEnded:
+            [self moviePlayDidEnd:self.ijkPlayer];
+            break;
+
+        case IJKMPMovieFinishReasonUserExited:
+            break;
+
+        case IJKMPMovieFinishReasonPlaybackError:
+            [self failedToPlayToEndTimeError:self.ijkPlayer];
+            break;
+
+        default:
+            break;
+    }
+}
+
+- (void)mediaIsPreparedToPlayDidChange:(NSNotification*)notification
+{
+}
+
+- (void)moviePlayBackStateDidChange:(NSNotification*)notification
+{
+    //    MPMoviePlaybackStateStopped,
+    //    MPMoviePlaybackStatePlaying,
+    //    MPMoviePlaybackStatePaused,
+    //    MPMoviePlaybackStateInterrupted,
+    //    MPMoviePlaybackStateSeekingForward,
+    //    MPMoviePlaybackStateSeekingBackward
+
+    switch (self.ijkPlayer.playbackState)
+    {
+        case IJKMPMoviePlaybackStateStopped: {
+            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: stoped", (int)self.ijkPlayer.playbackState);
+            self.state = MKRAVPlayerStateStopped;
+            break;
+        }
+        case IJKMPMoviePlaybackStatePlaying: {
+            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: playing", (int)self.ijkPlayer.playbackState);
+            self.state = MKRAVPlayerStatePlaying;
+            break;
+        }
+        case IJKMPMoviePlaybackStatePaused: {
+            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: paused", (int)self.ijkPlayer.playbackState);
+            self.state = MKRAVPlayerStatePause;
+            break;
+        }
+        case IJKMPMoviePlaybackStateInterrupted: {
+            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: interrupted", (int)self.ijkPlayer.playbackState);
+            break;
+        }
+        case IJKMPMoviePlaybackStateSeekingForward:
+        case IJKMPMoviePlaybackStateSeekingBackward: {
+            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: seeking", (int)self.ijkPlayer.playbackState);
+            self.state = MKRAVPlayerStateBuffering;
+            break;
+        }
+        default: {
+            NSLog(@"IJKMPMoviePlayBackStateDidChange %d: unknown", (int)self.ijkPlayer.playbackState);
+            break;
+        }
+    }
+}
+
 #pragma mark - KVO
 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
     if (context != PlayerStatusObservationContext) {

+ 1 - 1
fastlane/Fastfile

@@ -20,7 +20,7 @@ git_add(path: ".")
 
 #    git commit
 
-git_commit(path: ".", message: "添加专辑类播放资源枚举")
+git_commit(path: ".", message: "添加ijkplayer 解决iOS16 无法播放.m3u8资源")
 
 #    git push origin master
 

+ 14 - 12
fastlane/README.md

@@ -1,28 +1,30 @@
 fastlane documentation
-================
+----
+
 # Installation
 
 Make sure you have the latest version of the Xcode command line tools installed:
 
-```
+```sh
 xcode-select --install
 ```
 
-Install _fastlane_ using
-```
-[sudo] gem install fastlane -NV
-```
-or alternatively using `brew cask install fastlane`
+For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
 
 # Available Actions
+
 ### ManagerLib
+
+```sh
+[bundle exec] fastlane ManagerLib
 ```
-fastlane ManagerLib
-```
+
 ManagerLib 使用这个航道 可以快速的对自己的私有库,进行升级维护
 
 ----
 
-This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run.
-More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
-The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
+This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
+
+More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
+
+The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).

+ 1 - 1
upgrade.sh

@@ -1 +1 @@
-fastlane ManagerLib tag:0.0.3 target:MKRRadioManager
+fastlane ManagerLib tag:0.0.4 target:MKRRadioManager