张国栋 há 1 mês atrás
pai
commit
5efb01bc3e

+ 4 - 0
AICityProperty/AICity.xcodeproj/project.pbxproj

@@ -65,6 +65,7 @@
 		93C55BFC2EA8851400AEB59E /* emptyTCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93C55BFB2EA8851400AEB59E /* emptyTCell.xib */; };
 		93C55BFD2EA8851400AEB59E /* emptyTCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 93C55BF92EA8851400AEB59E /* emptyTCell.h */; };
 		93C55BFE2EA8851400AEB59E /* emptyTCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93C55BFA2EA8851400AEB59E /* emptyTCell.m */; };
+		93C55C002EA89E5600AEB59E /* JXSuperPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 93C55BFF2EA89E5600AEB59E /* JXSuperPlayer.h */; };
 		93CB0FE42EA7A87C00ACFECB /* CommentItemCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93CB0FE32EA7A87C00ACFECB /* CommentItemCell.xib */; };
 		93CB0FE52EA7A87C00ACFECB /* CommentItemCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 93CB0FE22EA7A87C00ACFECB /* CommentItemCell.m */; };
 		93CB0FE62EA7A87C00ACFECB /* CommentItemCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 93CB0FE12EA7A87C00ACFECB /* CommentItemCell.h */; };
@@ -260,6 +261,7 @@
 		93C55BF92EA8851400AEB59E /* emptyTCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = emptyTCell.h; sourceTree = "<group>"; };
 		93C55BFA2EA8851400AEB59E /* emptyTCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = emptyTCell.m; sourceTree = "<group>"; };
 		93C55BFB2EA8851400AEB59E /* emptyTCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = emptyTCell.xib; sourceTree = "<group>"; };
+		93C55BFF2EA89E5600AEB59E /* JXSuperPlayer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JXSuperPlayer.h; sourceTree = "<group>"; };
 		93CB0FE12EA7A87C00ACFECB /* CommentItemCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CommentItemCell.h; sourceTree = "<group>"; };
 		93CB0FE22EA7A87C00ACFECB /* CommentItemCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CommentItemCell.m; sourceTree = "<group>"; };
 		93CB0FE32EA7A87C00ACFECB /* CommentItemCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CommentItemCell.xib; sourceTree = "<group>"; };
@@ -525,6 +527,7 @@
 				86C2ECC82EA664260059A057 /* NetworkConfig.m */,
 				86C2ECC62EA664180059A057 /* NewHomeViewController.m */,
 				86C2ECC32EA663410059A057 /* JXAVPlayer.m */,
+				93C55BFF2EA89E5600AEB59E /* JXSuperPlayer.h */,
 				86C2ECC42EA663410059A057 /* JXSuperPlayer.m */,
 				86C2ECBE2EA663310059A057 /* JXAnalytics.m */,
 				86C2ECBF2EA663310059A057 /* JXAPIService.m */,
@@ -979,6 +982,7 @@
 			isa = PBXHeadersBuildPhase;
 			buildActionMask = 2147483647;
 			files = (
+				93C55C002EA89E5600AEB59E /* JXSuperPlayer.h in Headers */,
 				93C55BF52EA87CFC00AEB59E /* CommentFooterView.h in Headers */,
 				93A566CE2EA72F4A00818C54 /* GDNavigationController.h in Headers */,
 				93A566DA2EA73C7500818C54 /* EXTView.h in Headers */,

BIN
AICityProperty/AICity.xcworkspace/xcuserdata/zhangguodong.xcuserdatad/UserInterfaceState.xcuserstate


+ 21 - 0
AICityProperty/AICity/Assets.xcassets/b_jdt.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "b_jdt@3x-2.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AICityProperty/AICity/Assets.xcassets/b_jdt.imageset/b_jdt@3x-2.png


+ 21 - 0
AICityProperty/AICity/Assets.xcassets/b_jdtb.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "b_jdtb@3x-2.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AICityProperty/AICity/Assets.xcassets/b_jdtb.imageset/b_jdtb@3x-2.png


+ 21 - 0
AICityProperty/AICity/Assets.xcassets/jdt.imageset/Contents.json

@@ -0,0 +1,21 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "jdt.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AICityProperty/AICity/Assets.xcassets/jdt.imageset/jdt.png


+ 3 - 0
AICityProperty/AICity/JuXing/Player/JXSuperPlayer.m

@@ -263,6 +263,9 @@
             
         case PLAY_EVT_PLAY_PROGRESS: {
             // 播放进度(由progressTimer处理,这里不处理)
+            
+            float progress = [param[@"EVT_PLAY_PROGRESS"] floatValue] / [param[@"EVT_PLAY_DURATION"] floatValue] ;
+            [[NSNotificationCenter defaultCenter] postNotificationName:@"videoProgressChanged" object:nil userInfo:@{@"progress":@(progress),@"fileId":self.lastPlayParams[@"fileId"]}];
             break;
         }
             

+ 35 - 11
AICityProperty/AICity/JuXing/ViewControllers/JXDetailViewController.m

@@ -17,7 +17,8 @@
 #import <AVFoundation/AVFoundation.h>
 #import "JXCollectionViewController.h"
 #import "JXCommentViewController.h"
-@interface JXDetailViewController () <JXSuperPlayerDelegate, UICollectionViewDelegate, UICollectionViewDataSource,JXCollectionViewControllerDelegate>
+#import <TXLiteAVSDK_Player/TXLiteAVSDK.h>
+@interface JXDetailViewController () <JXSuperPlayerDelegate, UICollectionViewDelegate, UICollectionViewDataSource,JXCollectionViewControllerDelegate,TXVodPlayListener>
 
 // 播放器
 @property (nonatomic, strong) UIView *playerContainer;
@@ -40,7 +41,8 @@
 @property (nonatomic, strong) NSArray<JXEpisode *> *episodes;
 @property (nonatomic, strong) JXInteraction *interaction;
 @property (nonatomic, assign) NSInteger currentEpisodeIndex;
-
+@property (strong, nonatomic) UISlider *videoSlider;
+@property (nonatomic,assign) BOOL isHuadong;
 @end
 
 @implementation JXDetailViewController
@@ -61,7 +63,7 @@
     
     // 隐藏导航栏返回按钮
     self.navigationItem.hidesBackButton = YES;
-    
+    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeProgress:) name:@"videoProgressChanged" object:nil];
     [self setupUI];
     [self loadData];
 }
@@ -183,16 +185,9 @@
     // 创建播放器
     JXSuperPlayer *player = [[JXSuperPlayer alloc] initWithContainerView:playerContainer];
     player.delegate = self;
-    
-    
-    // 标题
-   
-    
     // 右侧互动按钮
     [self setupInteractionButtonsForCell:cell];
     
-   
-    
     UILabel * seeL = [[UILabel alloc] initWithFrame:CGRectMake(16, kScreenHeight - 14-safebottom, SCREEN_WIDTH - 32, 14)];
     seeL.font = [UIFont systemFontOfSize:14 weight:UIFontWeightMedium];
     seeL.textColor = [UIColor colorWithRed:173/255.0 green:173/255.0 blue:173/255.0 alpha:1];
@@ -217,6 +212,23 @@
     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showHJ:)];
     [bottomView addGestureRecognizer:tap];
     
+    UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(16,34, SCREEN_WIDTH-32, 2)];
+    [bottomView addSubview:slider];
+    slider.maximumValue = 1;
+    slider.minimumValue = 0;
+    [slider setThumbImage:[UIImage imageNamed:@"b_jdt.png"] forState:UIControlStateNormal];
+    [slider setThumbImage:[UIImage imageNamed:@"b_jdtb.png"] forState:UIControlStateHighlighted];
+    [slider setMinimumTrackImage:[UIImage imageNamed:@"jdt.png"] forState:UIControlStateNormal];
+    [slider setMinimumTrackImage:[UIImage imageNamed:@"jdt.png"] forState:UIControlStateHighlighted];
+    [slider setMaximumTrackImage:[UIImage imageNamed:@"jdt.png"] forState:UIControlStateNormal];
+    [slider setMaximumTrackImage:[UIImage imageNamed:@"jdt.png"] forState:UIControlStateHighlighted] ;
+    [slider setMinimumTrackTintColor:COLOR(0, 0, 0, 0.1)];
+    [slider setMaximumTrackTintColor:COLOR(0, 0, 0, 0.1)];
+    slider.alpha = 0.6;
+    self.videoSlider = slider;
+    
+    
+    
     UILabel *descLabel = [[UILabel alloc] init];
     descLabel.font = [UIFont systemFontOfSize:15 weight:UIFontWeightMedium];
     descLabel.textColor = [UIColor whiteColor];
@@ -314,8 +326,20 @@
         NSLog(@"[JXShortDrama] 🗨️ commentVC present 完成!");
     }];
 }
+- (void)changeProgress:(NSNotification *)niti{
+    if (!self.isHuadong){
+        NSDictionary *user = niti.userInfo;
+        JXEpisode *episode = self.episodes[self.currentEpisodeIndex];
 
-
+        if ([user[@"fileId"] isEqualToString:episode.fileId] ) {
+            float progress = [user[@"progress"] floatValue];
+            self.videoSlider.value = progress;
+            NSLog(@"进度--%f",progress);
+        }
+        
+    }
+    
+}
 
 - (void)collectionViewControllerDidSelectEpisode:(NSString *)episodeId {
     NSLog(@"[JXShortDrama] 选择播放剧集: %@", episodeId);

+ 116 - 0
AICityProperty/JXSuperPlayer.h

@@ -0,0 +1,116 @@
+//
+//  JXSuperPlayer.h
+//  AICity
+//
+//  Created by TogetherWatch on 2025-10-20.
+//  Feature: 010-ui-ios - 腾讯云SuperPlayer封装
+//  对标Android: JuXingSuperPlayer.kt
+//
+
+#import <Foundation/Foundation.h>
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * SuperPlayer播放状态
+ */
+typedef NS_ENUM(NSInteger, JXSuperPlayerState) {
+    JXSuperPlayerStateIdle,      // 空闲
+    JXSuperPlayerStatePreparing, // 准备中
+    JXSuperPlayerStatePlaying,   // 播放中
+    JXSuperPlayerStatePaused,    // 暂停
+    JXSuperPlayerStateCompleted, // 播放完成
+    JXSuperPlayerStateError      // 错误
+};
+
+/**
+ * SuperPlayer回调协议
+ */
+@protocol JXSuperPlayerDelegate <NSObject>
+
+@optional
+- (void)superPlayerDidChangeState:(JXSuperPlayerState)state;
+- (void)superPlayerDidUpdateProgress:(NSTimeInterval)currentTime duration:(NSTimeInterval)duration;
+- (void)superPlayerDidFailWithError:(NSError *)error;
+
+@end
+
+/**
+ * 腾讯云SuperPlayer封装
+ * 
+ * 功能:
+ * - 支持FileID+psign播放(DRM)
+ * - 支持URL播放
+ * - 自动解析AppID(从psign的JWT中提取)
+ * - 播放状态管理
+ * - 生命周期管理
+ * 
+ * 对标Android: JuXingSuperPlayer.kt
+ */
+@interface JXSuperPlayer : NSObject
+
+@property (nonatomic, weak) id<JXSuperPlayerDelegate> delegate;
+@property (nonatomic, strong, readonly) UIView *playerView;
+@property (nonatomic, assign, readonly) JXSuperPlayerState state;
+
+/**
+ * 初始化
+ * @param containerView 播放器容器视图
+ */
+- (instancetype)initWithContainerView:(UIView *)containerView;
+
+/**
+ * 播放视频(FileID模式 - DRM推荐)
+ * @param appId 腾讯云AppID
+ * @param fileId 腾讯云FileID
+ * @param psign 播放签名(JWT)
+ */
+- (void)playWithAppId:(NSString *)appId
+               fileId:(NSString *)fileId
+                psign:(NSString *)psign;
+
+/**
+ * 播放视频(URL模式)
+ * @param url 视频URL
+ */
+- (void)playWithURL:(NSString *)url;
+
+/**
+ * 播放控制
+ */
+- (void)play;
+- (void)pause;
+- (void)stop;
+- (void)resume;
+
+/**
+ * 跳转
+ */
+- (void)seekToTime:(NSTimeInterval)time;
+
+/**
+ * 获取播放信息
+ */
+- (NSTimeInterval)currentTime;
+- (NSTimeInterval)duration;
+- (BOOL)isPlaying;
+
+/**
+ * 释放资源
+ */
+- (void)releasePlayer;
+
+/**
+ * 从psign(JWT)中提取AppID
+ * @param psign JWT格式的播放签名
+ * @return AppID字符串,解析失败返回nil
+ */
++ (nullable NSString *)extractAppIdFromPsign:(NSString *)psign;
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+
+