Browse Source

Merge pull request #103 from Tencent/feature/ios_background_toggle

feat(iOS): 添加外部设置VAP退后台时行为的能力;修改QGVAPWrapView里的方法命名
Cass 4 years ago
parent
commit
aa680c225d

+ 1 - 1
QGVAPlayer.podspec

@@ -16,7 +16,7 @@ Pod::Spec.new do |spec|
   #
   #
 
 
   spec.name         = "QGVAPlayer"
   spec.name         = "QGVAPlayer"
-  spec.version      = "1.0.10"
+  spec.version      = "1.0.11"
   spec.summary      = "video animation player."
   spec.summary      = "video animation player."
   spec.platform     = :ios, "8.0"
   spec.platform     = :ios, "8.0"
 
 

+ 23 - 0
iOS/CHANGELOG.md

@@ -0,0 +1,23 @@
+## iOS 1.0.11
+
+**feature**
+
+- UIView(VAP) 新增 hwd_enterBackgroundOP,退后台时可以控制是暂停/结束行为[#issue102](https://github.com/Tencent/vap/issues/102)
+- QGVAPWrapView 补齐 stop/pause/resume功能,并修改了方法的命名
+
+
+
+## iOS 1.0.10
+
+**bugfix**
+
+- 解决退后台后回复可能出现花屏的问题
+
+
+
+## iOS 1.0.9
+
+**feature**
+
+- 添加VTSession失效时的重建逻辑(Seek关键帧,解码并丢弃,直到当前帧)
+- 将VAP默认行为由退后台时结束播放改为退后台时暂停,进入前台时恢复

+ 10 - 5
iOS/QGVAPlayer/QGVAPlayer/Classes/QGVAPWrapView.h

@@ -54,14 +54,19 @@ typedef NS_ENUM(NSUInteger, QGVAPWrapViewContentMode) {
 // 是否在播放完成后自动移除内部VAPView, 如果外部用法会复用当前View,可以不移除
 // 是否在播放完成后自动移除内部VAPView, 如果外部用法会复用当前View,可以不移除
 @property (nonatomic, assign) BOOL autoDestoryAfterFinish;
 @property (nonatomic, assign) BOOL autoDestoryAfterFinish;
 
 
-- (void)vapWrapView_playHWDMP4:(NSString *)filePath
-                   repeatCount:(NSInteger)repeatCount
-                      delegate:(id<VAPWrapViewDelegate>)delegate;
+- (void)playHWDMP4:(NSString *)filePath
+       repeatCount:(NSInteger)repeatCount
+          delegate:(id<VAPWrapViewDelegate>)delegate;
+
+- (void)stopHWDMP4;
+
+- (void)pauseHWDMP4;
+- (void)resumeHWDMP4;
 
 
 //增加点击的手势识别, 如果开启了autoDestoryAfterFinish,那么手势将在播放完毕后失效
 //增加点击的手势识别, 如果开启了autoDestoryAfterFinish,那么手势将在播放完毕后失效
-- (void)vapWrapView_addVapTapGesture:(VAPGestureEventBlock)handler;
+- (void)addVapTapGesture:(VAPGestureEventBlock)handler;
 //手势识别通用接口, 如果开启了autoDestoryAfterFinish,那么手势将在播放完毕后失效
 //手势识别通用接口, 如果开启了autoDestoryAfterFinish,那么手势将在播放完毕后失效
-- (void)vapWrapView_addVapGesture:(UIGestureRecognizer *)gestureRecognizer callback:(VAPGestureEventBlock)handler;
+- (void)addVapGesture:(UIGestureRecognizer *)gestureRecognizer callback:(VAPGestureEventBlock)handler;
 
 
 
 
 /*
 /*

+ 15 - 3
iOS/QGVAPlayer/QGVAPlayer/Classes/QGVAPWrapView.m

@@ -52,7 +52,7 @@
     }
     }
 }
 }
 
 
-- (void)vapWrapView_playHWDMP4:(NSString *)filePath
+- (void)playHWDMP4:(NSString *)filePath
                    repeatCount:(NSInteger)repeatCount
                    repeatCount:(NSInteger)repeatCount
                       delegate:(id<VAPWrapViewDelegate>)delegate {
                       delegate:(id<VAPWrapViewDelegate>)delegate {
     
     
@@ -62,12 +62,24 @@
     [self.vapView playHWDMP4:filePath repeatCount:repeatCount delegate:self];
     [self.vapView playHWDMP4:filePath repeatCount:repeatCount delegate:self];
 }
 }
 
 
-- (void)vapWrapView_addVapGesture:(UIGestureRecognizer *)gestureRecognizer callback:(VAPGestureEventBlock)handler {
+- (void)stopHWDMP4 {
+    [self.vapView stopHWDMP4];
+}
+
+- (void)pauseHWDMP4 {
+    [self.vapView pauseHWDMP4];
+}
+
+- (void)resumeHWDMP4 {
+    [self.vapView resumeHWDMP4];
+}
+
+- (void)addVapGesture:(UIGestureRecognizer *)gestureRecognizer callback:(VAPGestureEventBlock)handler {
     [self initVAPViewIfNeed];
     [self initVAPViewIfNeed];
     [self.vapView addVapGesture:gestureRecognizer callback:handler];
     [self.vapView addVapGesture:gestureRecognizer callback:handler];
 }
 }
 
 
-- (void)vapWrapView_addVapTapGesture:(VAPGestureEventBlock)handler {
+- (void)addVapTapGesture:(VAPGestureEventBlock)handler {
     [self initVAPViewIfNeed];
     [self initVAPViewIfNeed];
     [self.vapView addVapTapGesture:handler];
     [self.vapView addVapTapGesture:handler];
 }
 }

+ 8 - 1
iOS/QGVAPlayer/QGVAPlayer/Classes/UIView+VAP.h

@@ -17,6 +17,13 @@
 #import "VAPMacros.h"
 #import "VAPMacros.h"
 #import "QGVAPLogger.h"
 #import "QGVAPLogger.h"
 
 
+// 退后台时的行为
+typedef NS_ENUM(NSUInteger, HWDMP4EBOperationType) {
+    HWDMP4EBOperationTypeStop,              // 退后台时结束VAP播放
+    HWDMP4EBOperationTypePauseAndResume,    // 退后台时暂停、回到前台时自动恢复 (需要从关键帧解码到当前帧以解决VTSession失效问题,建议低端机型不要设置此选项,暂停时间较长、CPU占用较大)
+    HWDMP4EBOperationTypeDoNothing,         // VAP自身不进行控制,当外部进行控制时可以使用这个,仅用于防止覆盖外界的pause调用的问题
+};
+
 @class QGMP4AnimatedImageFrame,QGVAPConfigModel, QGVAPSourceInfo;
 @class QGMP4AnimatedImageFrame,QGVAPConfigModel, QGVAPSourceInfo;
 /** 注意:回调方法会在子线程被执行。*/
 /** 注意:回调方法会在子线程被执行。*/
 @protocol HWDMP4PlayDelegate <NSObject>
 @protocol HWDMP4PlayDelegate <NSObject>
@@ -44,6 +51,7 @@
 @property (nonatomic, strong) NSString                  *hwd_MP4FilePath;
 @property (nonatomic, strong) NSString                  *hwd_MP4FilePath;
 @property (nonatomic, assign) NSInteger                 hwd_fps;         //fps for dipslay, each frame's duration would be set by fps value before display.
 @property (nonatomic, assign) NSInteger                 hwd_fps;         //fps for dipslay, each frame's duration would be set by fps value before display.
 @property (nonatomic, assign) BOOL                      hwd_renderByOpenGL;      //是否使用opengl渲染,默认使用metal
 @property (nonatomic, assign) BOOL                      hwd_renderByOpenGL;      //是否使用opengl渲染,默认使用metal
+@property (nonatomic, assign) HWDMP4EBOperationType     hwd_enterBackgroundOP;   // 在退后台时的行为,默认为结束
 
 
 - (void)playHWDMp4:(NSString *)filePath;
 - (void)playHWDMp4:(NSString *)filePath;
 - (void)playHWDMP4:(NSString *)filePath delegate:(id<HWDMP4PlayDelegate>)delegate;
 - (void)playHWDMP4:(NSString *)filePath delegate:(id<HWDMP4PlayDelegate>)delegate;
@@ -51,7 +59,6 @@
 
 
 - (void)stopHWDMP4;
 - (void)stopHWDMP4;
 
 
-/// 注意,一旦退后台就会强制stop,退回前台后再resume无效
 - (void)pauseHWDMP4;
 - (void)pauseHWDMP4;
 - (void)resumeHWDMP4;
 - (void)resumeHWDMP4;
 
 

+ 23 - 5
iOS/QGVAPlayer/QGVAPlayer/Classes/UIView+VAP.m

@@ -73,7 +73,28 @@ NSInteger const VapMaxCompatibleVersion = 2;
 }
 }
 
 
 - (void)hwd_didReceiveEnterBackgroundNotification:(NSNotification *)notification {
 - (void)hwd_didReceiveEnterBackgroundNotification:(NSNotification *)notification {
-    [self pauseHWDMP4];
+    switch (self.hwd_enterBackgroundOP) {
+        case HWDMP4EBOperationTypePauseAndResume:
+            [self pauseHWDMP4];
+            break;
+        case HWDMP4EBOperationTypeDoNothing:
+            break;
+            
+        default:
+            [self stopHWDMP4];
+    }
+}
+
+- (void)hwd_didReceiveWillEnterForegroundNotification:(NSNotification *)notification {
+    switch (self.hwd_enterBackgroundOP) {
+        case HWDMP4EBOperationTypePauseAndResume:
+            [self resumeHWDMP4];
+            break;
+            
+        default:
+            break;
+    }
+    
 }
 }
 
 
 - (void)hwd_didReceiveSeekStartNotification:(NSNotification *)notification {
 - (void)hwd_didReceiveSeekStartNotification:(NSNotification *)notification {
@@ -150,10 +171,6 @@ NSInteger const VapMaxCompatibleVersion = 2;
     [self hwd_stopHWDMP4];
     [self hwd_stopHWDMP4];
 }
 }
 
 
-- (void)hwd_didReceiveWillEnterForegroundNotification:(NSNotification *)notification {
-    [self resumeHWDMP4];
-}
-
 - (void)hwd_loadMetalViewIfNeed:(QGHWDTextureBlendMode)mode {
 - (void)hwd_loadMetalViewIfNeed:(QGHWDTextureBlendMode)mode {
     
     
     if (self.hwd_renderByOpenGL) {
     if (self.hwd_renderByOpenGL) {
@@ -560,6 +577,7 @@ NSInteger const VapMaxCompatibleVersion = 2;
 //category methods
 //category methods
 HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_onPause, setHwd_onPause, BOOL)
 HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_onPause, setHwd_onPause, BOOL)
 HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_onSeek, setHwd_onSeek, BOOL)
 HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_onSeek, setHwd_onSeek, BOOL)
+HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_enterBackgroundOP, setHwd_enterBackgroundOP, HWDMP4EBOperationType)
 HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_renderByOpenGL, setHwd_renderByOpenGL, BOOL)
 HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_renderByOpenGL, setHwd_renderByOpenGL, BOOL)
 HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_isFinish, setHwd_isFinish, BOOL)
 HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_isFinish, setHwd_isFinish, BOOL)
 HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_fps, setHwd_fps, NSInteger)
 HWDSYNTH_DYNAMIC_PROPERTY_CTYPE(hwd_fps, setHwd_fps, NSInteger)

+ 12 - 0
iOS/QGVAPlayerDemo/QGVAPlayerDemo.xcodeproj/project.pbxproj

@@ -19,6 +19,9 @@
 		63BAD43422F09D2800EAD4C4 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 63BAD43322F09D2700EAD4C4 /* libz.tbd */; };
 		63BAD43422F09D2800EAD4C4 /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 63BAD43322F09D2700EAD4C4 /* libz.tbd */; };
 		63BAD44322F0A02C00EAD4C4 /* QGVAPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63BAD43B22F09D6800EAD4C4 /* QGVAPlayer.framework */; };
 		63BAD44322F0A02C00EAD4C4 /* QGVAPlayer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 63BAD43B22F09D6800EAD4C4 /* QGVAPlayer.framework */; };
 		63BAD44422F0A02C00EAD4C4 /* QGVAPlayer.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 63BAD43B22F09D6800EAD4C4 /* QGVAPlayer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
 		63BAD44422F0A02C00EAD4C4 /* QGVAPlayer.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 63BAD43B22F09D6800EAD4C4 /* QGVAPlayer.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+		BA964B5F268315E6003265F2 /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = BA964B5D268315E6003265F2 /* CHANGELOG.md */; };
+		BA964B6326831AF1003265F2 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = BA964B6126831AF1003265F2 /* README.md */; };
+		BA964B6526831BB6003265F2 /* QGVAPlayer.podspec in Resources */ = {isa = PBXBuildFile; fileRef = BA964B6426831BB6003265F2 /* QGVAPlayer.podspec */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
 /* Begin PBXContainerItemProxy section */
 /* Begin PBXContainerItemProxy section */
@@ -100,6 +103,9 @@
 		63BAD3B822F09BAF00EAD4C4 /* Resource */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Resource; sourceTree = "<group>"; };
 		63BAD3B822F09BAF00EAD4C4 /* Resource */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Resource; sourceTree = "<group>"; };
 		63BAD43322F09D2700EAD4C4 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
 		63BAD43322F09D2700EAD4C4 /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
 		63BAD43522F09D6800EAD4C4 /* QGVAPlayer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = QGVAPlayer.xcodeproj; path = ../../QGVAPlayer/QGVAPlayer.xcodeproj; sourceTree = "<group>"; };
 		63BAD43522F09D6800EAD4C4 /* QGVAPlayer.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = QGVAPlayer.xcodeproj; path = ../../QGVAPlayer/QGVAPlayer.xcodeproj; sourceTree = "<group>"; };
+		BA964B5D268315E6003265F2 /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = CHANGELOG.md; path = ../CHANGELOG.md; sourceTree = "<group>"; };
+		BA964B6126831AF1003265F2 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
+		BA964B6426831BB6003265F2 /* QGVAPlayer.podspec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = QGVAPlayer.podspec; path = ../../QGVAPlayer.podspec; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
 
 
 /* Begin PBXFrameworksBuildPhase section */
 /* Begin PBXFrameworksBuildPhase section */
@@ -132,6 +138,9 @@
 		63BAD37A22F09B1200EAD4C4 = {
 		63BAD37A22F09B1200EAD4C4 = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				BA964B6426831BB6003265F2 /* QGVAPlayer.podspec */,
+				BA964B6126831AF1003265F2 /* README.md */,
+				BA964B5D268315E6003265F2 /* CHANGELOG.md */,
 				63BAD3B822F09BAF00EAD4C4 /* Resource */,
 				63BAD3B822F09BAF00EAD4C4 /* Resource */,
 				63BAD38522F09B1200EAD4C4 /* QGVAPlayerDemo */,
 				63BAD38522F09B1200EAD4C4 /* QGVAPlayerDemo */,
 				63BAD39E22F09B1500EAD4C4 /* QGVAPlayerDemoTests */,
 				63BAD39E22F09B1500EAD4C4 /* QGVAPlayerDemoTests */,
@@ -332,7 +341,10 @@
 			isa = PBXResourcesBuildPhase;
 			isa = PBXResourcesBuildPhase;
 			buildActionMask = 2147483647;
 			buildActionMask = 2147483647;
 			files = (
 			files = (
+				BA964B6526831BB6003265F2 /* QGVAPlayer.podspec in Resources */,
+				BA964B6326831AF1003265F2 /* README.md in Resources */,
 				63BAD3B922F09BAF00EAD4C4 /* Resource in Resources */,
 				63BAD3B922F09BAF00EAD4C4 /* Resource in Resources */,
+				BA964B5F268315E6003265F2 /* CHANGELOG.md in Resources */,
 				63BAD39322F09B1500EAD4C4 /* LaunchScreen.storyboard in Resources */,
 				63BAD39322F09B1500EAD4C4 /* LaunchScreen.storyboard in Resources */,
 				63BAD39022F09B1500EAD4C4 /* Assets.xcassets in Resources */,
 				63BAD39022F09B1500EAD4C4 /* Assets.xcassets in Resources */,
 				63BAD38E22F09B1200EAD4C4 /* Main.storyboard in Resources */,
 				63BAD38E22F09B1200EAD4C4 /* Main.storyboard in Resources */,

+ 19 - 6
iOS/QGVAPlayerDemo/QGVAPlayerDemo/ViewController.m

@@ -55,14 +55,14 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
     //vap-经典效果
     //vap-经典效果
     _vapButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, CGRectGetWidth(self.view.frame), 90)];
     _vapButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 100, CGRectGetWidth(self.view.frame), 90)];
     _vapButton.backgroundColor = [UIColor lightGrayColor];
     _vapButton.backgroundColor = [UIColor lightGrayColor];
-    [_vapButton setTitle:@"电竞方案" forState:UIControlStateNormal];
+    [_vapButton setTitle:@"电竞方案(退后台结束)" forState:UIControlStateNormal];
     [_vapButton addTarget:self action:@selector(playVap) forControlEvents:UIControlEventTouchUpInside];
     [_vapButton addTarget:self action:@selector(playVap) forControlEvents:UIControlEventTouchUpInside];
     [self.view addSubview:_vapButton];
     [self.view addSubview:_vapButton];
     
     
     //vapx-融合效果
     //vapx-融合效果
     _vapxButton = [[UIButton alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_vapButton.frame)+60, CGRectGetWidth(self.view.frame), 90)];
     _vapxButton = [[UIButton alloc] initWithFrame:CGRectMake(0, CGRectGetMaxY(_vapButton.frame)+60, CGRectGetWidth(self.view.frame), 90)];
     _vapxButton.backgroundColor = [UIColor lightGrayColor];
     _vapxButton.backgroundColor = [UIColor lightGrayColor];
-    [_vapxButton setTitle:@"融合特效" forState:UIControlStateNormal];
+    [_vapxButton setTitle:@"融合特效(退后台暂停/恢复)" forState:UIControlStateNormal];
     [_vapxButton addTarget:self action:@selector(playVapx) forControlEvents:UIControlEventTouchUpInside];
     [_vapxButton addTarget:self action:@selector(playVapx) forControlEvents:UIControlEventTouchUpInside];
     [self.view addSubview:_vapxButton];
     [self.view addSubview:_vapxButton];
     
     
@@ -83,6 +83,7 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
     mp4View.center = self.view.center;
     mp4View.center = self.view.center;
     [self.view addSubview:mp4View];
     [self.view addSubview:mp4View];
     mp4View.userInteractionEnabled = YES;
     mp4View.userInteractionEnabled = YES;
+    mp4View.hwd_enterBackgroundOP = HWDMP4EBOperationTypeStop;
     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onImageviewTap:)];
     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onImageviewTap:)];
     [mp4View addGestureRecognizer:tap];
     [mp4View addGestureRecognizer:tap];
     NSString *resPath = [NSString stringWithFormat:@"%@/Resource/demo.mp4", [[NSBundle mainBundle] resourcePath]];
     NSString *resPath = [NSString stringWithFormat:@"%@/Resource/demo.mp4", [[NSBundle mainBundle] resourcePath]];
@@ -99,6 +100,7 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
     [self.view addSubview:mp4View];
     [self.view addSubview:mp4View];
     mp4View.center = self.view.center;
     mp4View.center = self.view.center;
     mp4View.userInteractionEnabled = YES;
     mp4View.userInteractionEnabled = YES;
+    mp4View.hwd_enterBackgroundOP = HWDMP4EBOperationTypePauseAndResume; // ⚠️ 建议设置该选项时对机型进行判断,屏蔽低端机
     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onImageviewTap:)];
     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onImageviewTap:)];
     [mp4View addGestureRecognizer:tap];
     [mp4View addGestureRecognizer:tap];
     [mp4View playHWDMP4:mp4Path repeatCount:-1 delegate:self];
     [mp4View playHWDMP4:mp4Path repeatCount:-1 delegate:self];
@@ -106,16 +108,23 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
 
 
 /// 使用WrapView,支持ContentMode
 /// 使用WrapView,支持ContentMode
 - (void)playVapWithWrapView {
 - (void)playVapWithWrapView {
+    static BOOL pause = NO;
     QGVAPWrapView *wrapView = [[QGVAPWrapView alloc] initWithFrame:self.view.bounds];
     QGVAPWrapView *wrapView = [[QGVAPWrapView alloc] initWithFrame:self.view.bounds];
     wrapView.center = self.view.center;
     wrapView.center = self.view.center;
     wrapView.contentMode = QGVAPWrapViewContentModeAspectFit;
     wrapView.contentMode = QGVAPWrapViewContentModeAspectFit;
     wrapView.autoDestoryAfterFinish = YES;
     wrapView.autoDestoryAfterFinish = YES;
     [self.view addSubview:wrapView];
     [self.view addSubview:wrapView];
     NSString *resPath = [NSString stringWithFormat:@"%@/Resource/demo.mp4", [[NSBundle mainBundle] resourcePath]];
     NSString *resPath = [NSString stringWithFormat:@"%@/Resource/demo.mp4", [[NSBundle mainBundle] resourcePath]];
-    [wrapView vapWrapView_playHWDMP4:resPath repeatCount:-1 delegate:self];
-    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onImageviewTap:)];
-    [wrapView vapWrapView_addVapGesture:tap callback:^(UIGestureRecognizer *gestureRecognizer, BOOL insideSource, QGVAPSourceDisplayItem *source) {
-        
+    [wrapView playHWDMP4:resPath repeatCount:-1 delegate:self];
+    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doNothingonImageviewTap:)];
+    
+    __weak __typeof(wrapView) weakWrapView = wrapView;
+    [wrapView addVapGesture:tap callback:^(UIGestureRecognizer *gestureRecognizer, BOOL insideSource, QGVAPSourceDisplayItem *source) {
+        if ((pause = !pause)) {
+            [weakWrapView pauseHWDMP4];
+        } else {
+            [weakWrapView resumeHWDMP4];
+        }
     }];
     }];
 }
 }
 
 
@@ -179,6 +188,10 @@ void qg_VAP_Logger_handler(VAPLogLevel level, const char* file, int line, const
     [ges.view removeFromSuperview];
     [ges.view removeFromSuperview];
 }
 }
 
 
+- (void)doNothingonImageviewTap:(UIGestureRecognizer *)ges {
+    
+}
+
 #pragma mark - WrapViewDelegate
 #pragma mark - WrapViewDelegate
 
 
 //provide the content for tags, maybe text or url string ...
 //provide the content for tags, maybe text or url string ...

+ 11 - 4
iOS/README.md

@@ -34,8 +34,15 @@ VAP是企鹅电竞实现大礼物特效的高性能组件,基于H.264硬解码
     [mp4View playHWDMp4:resPath];//在view上播放该特效,按该view的大小进行渲染
     [mp4View playHWDMp4:resPath];//在view上播放该特效,按该view的大小进行渲染
 ```
 ```
 
 
+
+```
+2) 退后台时的行为
+mp4View.hwd_enterBackgroundOP = HWDMP4EBOperationTypeStop; // 默认为该项,退后台时结束播放
+mp4View.hwd_enterBackgroundOP = HWDMP4EBOperationTypePauseAndResume; // ⚠️ 建议设置该选项时对机型进行判断,屏蔽低端机
+```
+
 ```
 ```
-    2)代理回调
+    3)代理回调
 
 
     - (void)viewDidStartPlayMP4:(VAPView *)container {
     - (void)viewDidStartPlayMP4:(VAPView *)container {
     }
     }
@@ -65,7 +72,7 @@ VAP是企鹅电竞实现大礼物特效的高性能组件,基于H.264硬解码
 ```
 ```
 
 
 ```
 ```
-3)融合动画:delegate中实现下面两个接口,替换tag内容和下载图片
+4)融合动画:delegate中实现下面两个接口,替换tag内容和下载图片
 
 
 
 
 //provide the content for tags, maybe text or url string ...
 //provide the content for tags, maybe text or url string ...
@@ -91,7 +98,7 @@ VAP是企鹅电竞实现大礼物特效的高性能组件,基于H.264硬解码
 ```
 ```
 
 
 ```
 ```
-    4)手势识别
+    5)手势识别
 
 
     [mp4View addVapTapGesture:^(UIGestureRecognizer *gestureRecognizer, BOOL insideSource, QGVAPSourceDisplayItem *source) {
     [mp4View addVapTapGesture:^(UIGestureRecognizer *gestureRecognizer, BOOL insideSource, QGVAPSourceDisplayItem *source) {
         NSLog(@"click");
         NSLog(@"click");
@@ -102,7 +109,7 @@ VAP是企鹅电竞实现大礼物特效的高性能组件,基于H.264硬解码
 ```
 ```
 
 
 ```
 ```
-    5) contentMode 支持
+    6) contentMode 支持
 //note: 导入 QGVAPWrapView.h 头文件。通过创建 `QGVAPWrapView` 作为播放特效的 View。可以设置其`contentMode`属性。
 //note: 导入 QGVAPWrapView.h 头文件。通过创建 `QGVAPWrapView` 作为播放特效的 View。可以设置其`contentMode`属性。
 QGVAPWrapView *wrapView = [[QGVAPWrapView alloc] initWithFrame:self.view.bounds];
 QGVAPWrapView *wrapView = [[QGVAPWrapView alloc] initWithFrame:self.view.bounds];
 wrapView.contentMode = QGVAPWrapViewContentModeAspectFit;
 wrapView.contentMode = QGVAPWrapViewContentModeAspectFit;