Browse Source

合成封面优化

Steven 1 year ago
parent
commit
b7a60deb79
69 changed files with 2545 additions and 551 deletions
  1. 75 11
      KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj
  2. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_choose_image.imageset/Contents.json
  3. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_choose_image.imageset/cover_choose_image@2x.png
  4. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_choose_image.imageset/cover_choose_image@3x.png
  5. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_crop_image.imageset/Contents.json
  6. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_crop_image.imageset/cover_crop_image@2x.png
  7. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_crop_image.imageset/cover_crop_image@3x.png
  8. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/minework_Line.imageset/Contents.json
  9. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/minework_Line.imageset/minework_Line@2x.png
  10. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/minework_Line.imageset/minework_Line@3x.png
  11. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/Contents.json
  12. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/progressLoading_bg@2x.png
  13. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/progressLoading_bg@3x.png
  14. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progress_dot.imageset/Contents.json
  15. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progress_dot.imageset/progress_dot@2x.png
  16. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progress_dot.imageset/progress_dot@3x.png
  17. 22 0
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/Contents.json
  18. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/videoMerge_cover@2x.png
  19. BIN
      KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/videoMerge_cover@3x.png
  20. 54 33
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSAccompanyWebViewController.m
  21. 192 71
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSBaseWKWebViewController.m
  22. 2 1
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h
  23. 3 1
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m
  24. 3 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSVideoRecordManager.m
  25. 15 15
      KulexiuForTeacher/KulexiuForTeacher/Common/Define/KSDomain.h
  26. 13 0
      KulexiuForTeacher/KulexiuForTeacher/Common/LoadingManager/KSHudLoagingManager.h
  27. 41 0
      KulexiuForTeacher/KulexiuForTeacher/Common/LoadingManager/KSHudLoagingManager.m
  28. 24 0
      KulexiuForTeacher/KulexiuForTeacher/Common/LoadingManager/KSProgressLoadingView.h
  29. 89 0
      KulexiuForTeacher/KulexiuForTeacher/Common/LoadingManager/KSProgressLoadingView.m
  30. 104 0
      KulexiuForTeacher/KulexiuForTeacher/Common/LoadingManager/KSProgressLoadingView.xib
  31. 2 0
      KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/KSAudioAnimationView.h
  32. 9 0
      KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/KSAudioAnimationView.m
  33. 223 67
      KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/KSMediaMergeView.m
  34. 4 4
      KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/KSMergeAudioControlView.xib
  35. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/KSPlayerSliderView.m
  36. 0 272
      KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/MusicPublistAlert.xib
  37. 4 5
      KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/MediaEditor/KSMediaEditor.m
  38. 0 1
      KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Custom/PressRecord/KSAudioRecordManager.m
  39. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Common/Tools/GifRefresh/KSGifRefreshHeader.h
  40. 7 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Controller/MineViewController.m
  41. 1 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/View/MineActionView.h
  42. 6 3
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/View/MineFunctionView.m
  43. 8 10
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/View/MineFunctionView.xib
  44. 5 7
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/View/MineTeachToolView.xib
  45. 10 4
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/Controller/KSDraftMergeViewController.m
  46. 26 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/Controller/KSVideoCropViewController.h
  47. 253 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/Controller/KSVideoCropViewController.m
  48. 9 7
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/Controller/MineWorksViewController.m
  49. 24 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/KSCropImageNavView.h
  50. 60 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/KSCropImageNavView.m
  51. 101 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/KSCropImageNavView.xib
  52. 25 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/KSVideoImageSlider.h
  53. 133 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/KSVideoImageSlider.m
  54. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MineWorksBodyView.m
  55. 1 1
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MineWorksNavView.m
  56. 11 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MineWorksNavView.xib
  57. 21 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPubHeader.h
  58. 7 12
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublicContentView.h
  59. 15 24
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublicContentView.m
  60. 222 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublicContentView.xib
  61. 32 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublistAlert.h
  62. 138 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublistAlert.m
  63. 90 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublistAlert.xib
  64. 27 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCoverChooseView.h
  65. 59 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCoverChooseView.m
  66. 177 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCoverChooseView.xib
  67. 18 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCropImageViewCell.h
  68. 28 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCropImageViewCell.m
  69. 39 0
      KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCropImageViewCell.xib

+ 75 - 11
KulexiuForTeacher/KulexiuForTeacher.xcodeproj/project.pbxproj

@@ -621,11 +621,9 @@
 		BC38C4252AF900E100ABFCC2 /* KSNewAlertView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C4052AF900E100ABFCC2 /* KSNewAlertView.m */; };
 		BC38C4262AF900E100ABFCC2 /* KSMediaMergeView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C4072AF900E100ABFCC2 /* KSMediaMergeView.m */; };
 		BC38C4272AF900E100ABFCC2 /* KSVideoPlayerView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C40C2AF900E100ABFCC2 /* KSVideoPlayerView.m */; };
-		BC38C4282AF900E100ABFCC2 /* MusicPublistAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C40D2AF900E100ABFCC2 /* MusicPublistAlert.m */; };
 		BC38C4292AF900E100ABFCC2 /* KSAudioAnimationView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC38C40F2AF900E100ABFCC2 /* KSAudioAnimationView.xib */; };
 		BC38C42A2AF900E100ABFCC2 /* KSAudioPlayAnimationView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C4112AF900E100ABFCC2 /* KSAudioPlayAnimationView.m */; };
 		BC38C42B2AF900E100ABFCC2 /* KSMergeAudioControlView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC38C4142AF900E100ABFCC2 /* KSMergeAudioControlView.xib */; };
-		BC38C42C2AF900E100ABFCC2 /* MusicPublistAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC38C4152AF900E100ABFCC2 /* MusicPublistAlert.xib */; };
 		BC38C42D2AF900E100ABFCC2 /* KSPlayerSliderView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C4172AF900E100ABFCC2 /* KSPlayerSliderView.m */; };
 		BC38C42E2AF900E100ABFCC2 /* KSPlayerSliderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC38C4182AF900E100ABFCC2 /* KSPlayerSliderView.xib */; };
 		BC38C42F2AF900E100ABFCC2 /* KSMergeAudioControlView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C4192AF900E100ABFCC2 /* KSMergeAudioControlView.m */; };
@@ -647,6 +645,8 @@
 		BC38C48B2AFA207B00ABFCC2 /* KSEmptyStatusView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC38C4892AFA207A00ABFCC2 /* KSEmptyStatusView.xib */; };
 		BC38C48C2AFA207B00ABFCC2 /* KSEmptyStatusView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C48A2AFA207B00ABFCC2 /* KSEmptyStatusView.m */; };
 		BC38C48F2AFA20AB00ABFCC2 /* KSNewGifRefreshFooter.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C48E2AFA20AB00ABFCC2 /* KSNewGifRefreshFooter.m */; };
+		BC38C49D2AFA4C7D00ABFCC2 /* KSProgressLoadingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BC38C49B2AFA4C7C00ABFCC2 /* KSProgressLoadingView.xib */; };
+		BC38C49E2AFA4C7D00ABFCC2 /* KSProgressLoadingView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC38C49C2AFA4C7D00ABFCC2 /* KSProgressLoadingView.m */; };
 		BC3A4EB728DAFCF7001C4428 /* MusicTagView.m in Sources */ = {isa = PBXBuildFile; fileRef = BC3A4EB628DAFCF7001C4428 /* MusicTagView.m */; };
 		BC3ACD942890D60800060E97 /* FreezeListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC3ACD932890D60800060E97 /* FreezeListViewController.m */; };
 		BC3ACD972890D61400060E97 /* NoRecordViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BC3ACD962890D61400060E97 /* NoRecordViewController.m */; };
@@ -1078,6 +1078,18 @@
 		BCC0F7082A8CF13D00C4EFA4 /* KSDanInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC0F6FF2A8CF13D00C4EFA4 /* KSDanInputView.m */; };
 		BCC0F7092A8CF13D00C4EFA4 /* TXDanMuView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC0F7022A8CF13D00C4EFA4 /* TXDanMuView.m */; };
 		BCC305F828FD4C0800C39762 /* KSChatUserDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC305F728FD4C0800C39762 /* KSChatUserDetailViewController.m */; };
+		BCC408CD2AFCE0B700C60249 /* KSVideoCropViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408CC2AFCE0B600C60249 /* KSVideoCropViewController.m */; };
+		BCC408D62AFCE0D700C60249 /* KSCropImageNavView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC408CF2AFCE0D600C60249 /* KSCropImageNavView.xib */; };
+		BCC408D72AFCE0D700C60249 /* VideoCropImageViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408D02AFCE0D600C60249 /* VideoCropImageViewCell.m */; };
+		BCC408D82AFCE0D700C60249 /* KSVideoImageSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408D12AFCE0D600C60249 /* KSVideoImageSlider.m */; };
+		BCC408D92AFCE0D700C60249 /* KSCropImageNavView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408D22AFCE0D600C60249 /* KSCropImageNavView.m */; };
+		BCC408DA2AFCE0D700C60249 /* VideoCropImageViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC408D32AFCE0D600C60249 /* VideoCropImageViewCell.xib */; };
+		BCC408E52AFCE11900C60249 /* MusicPublistAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408DB2AFCE11700C60249 /* MusicPublistAlert.m */; };
+		BCC408E62AFCE11900C60249 /* MusicPublicContentView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408DC2AFCE11700C60249 /* MusicPublicContentView.m */; };
+		BCC408E72AFCE11900C60249 /* MusicPublicContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC408DD2AFCE11800C60249 /* MusicPublicContentView.xib */; };
+		BCC408E82AFCE11900C60249 /* VideoCoverChooseView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC408DF2AFCE11800C60249 /* VideoCoverChooseView.xib */; };
+		BCC408E92AFCE11900C60249 /* MusicPublistAlert.xib in Resources */ = {isa = PBXBuildFile; fileRef = BCC408E02AFCE11800C60249 /* MusicPublistAlert.xib */; };
+		BCC408EA2AFCE11900C60249 /* VideoCoverChooseView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCC408E32AFCE11900C60249 /* VideoCoverChooseView.m */; };
 		BCC583F428A9FA8100BAB4CF /* cloud_animation_9.png in Resources */ = {isa = PBXBuildFile; fileRef = BCC583D528A9FA8100BAB4CF /* cloud_animation_9.png */; };
 		BCC583F528A9FA8100BAB4CF /* cloud_animation_8.png in Resources */ = {isa = PBXBuildFile; fileRef = BCC583D628A9FA8100BAB4CF /* cloud_animation_8.png */; };
 		BCC583F628A9FA8100BAB4CF /* cloud_animation_20.png in Resources */ = {isa = PBXBuildFile; fileRef = BCC583D728A9FA8100BAB4CF /* cloud_animation_20.png */; };
@@ -2356,7 +2368,6 @@
 		BC38C4012AF900E100ABFCC2 /* KSPlayerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSPlayerView.m; sourceTree = "<group>"; };
 		BC38C4022AF900E100ABFCC2 /* UIView+KSCovertImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+KSCovertImage.m"; sourceTree = "<group>"; };
 		BC38C4032AF900E100ABFCC2 /* KSNewAlertView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSNewAlertView.xib; sourceTree = "<group>"; };
-		BC38C4042AF900E100ABFCC2 /* MusicPublistAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicPublistAlert.h; sourceTree = "<group>"; };
 		BC38C4052AF900E100ABFCC2 /* KSNewAlertView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSNewAlertView.m; sourceTree = "<group>"; };
 		BC38C4062AF900E100ABFCC2 /* KSAudioAnimationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSAudioAnimationView.h; sourceTree = "<group>"; };
 		BC38C4072AF900E100ABFCC2 /* KSMediaMergeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSMediaMergeView.m; sourceTree = "<group>"; };
@@ -2364,14 +2375,12 @@
 		BC38C4092AF900E100ABFCC2 /* KSPlayerSliderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSPlayerSliderView.h; sourceTree = "<group>"; };
 		BC38C40B2AF900E100ABFCC2 /* KSVideoPlayerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSVideoPlayerView.h; sourceTree = "<group>"; };
 		BC38C40C2AF900E100ABFCC2 /* KSVideoPlayerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSVideoPlayerView.m; sourceTree = "<group>"; };
-		BC38C40D2AF900E100ABFCC2 /* MusicPublistAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MusicPublistAlert.m; sourceTree = "<group>"; };
 		BC38C40E2AF900E100ABFCC2 /* UIView+KSCovertImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+KSCovertImage.h"; sourceTree = "<group>"; };
 		BC38C40F2AF900E100ABFCC2 /* KSAudioAnimationView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSAudioAnimationView.xib; sourceTree = "<group>"; };
 		BC38C4112AF900E100ABFCC2 /* KSAudioPlayAnimationView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSAudioPlayAnimationView.m; sourceTree = "<group>"; };
 		BC38C4122AF900E100ABFCC2 /* KSAudioPlayAnimationView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSAudioPlayAnimationView.h; sourceTree = "<group>"; };
 		BC38C4132AF900E100ABFCC2 /* KSPlayerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSPlayerView.h; sourceTree = "<group>"; };
 		BC38C4142AF900E100ABFCC2 /* KSMergeAudioControlView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSMergeAudioControlView.xib; sourceTree = "<group>"; };
-		BC38C4152AF900E100ABFCC2 /* MusicPublistAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MusicPublistAlert.xib; sourceTree = "<group>"; };
 		BC38C4162AF900E100ABFCC2 /* KSNewAlertView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSNewAlertView.h; sourceTree = "<group>"; };
 		BC38C4172AF900E100ABFCC2 /* KSPlayerSliderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSPlayerSliderView.m; sourceTree = "<group>"; };
 		BC38C4182AF900E100ABFCC2 /* KSPlayerSliderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSPlayerSliderView.xib; sourceTree = "<group>"; };
@@ -2407,6 +2416,9 @@
 		BC38C48A2AFA207B00ABFCC2 /* KSEmptyStatusView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSEmptyStatusView.m; sourceTree = "<group>"; };
 		BC38C48D2AFA20AB00ABFCC2 /* KSNewGifRefreshFooter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSNewGifRefreshFooter.h; sourceTree = "<group>"; };
 		BC38C48E2AFA20AB00ABFCC2 /* KSNewGifRefreshFooter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSNewGifRefreshFooter.m; sourceTree = "<group>"; };
+		BC38C49A2AFA4C7C00ABFCC2 /* KSProgressLoadingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSProgressLoadingView.h; sourceTree = "<group>"; };
+		BC38C49B2AFA4C7C00ABFCC2 /* KSProgressLoadingView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSProgressLoadingView.xib; sourceTree = "<group>"; };
+		BC38C49C2AFA4C7D00ABFCC2 /* KSProgressLoadingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSProgressLoadingView.m; sourceTree = "<group>"; };
 		BC3A4EB528DAFCF7001C4428 /* MusicTagView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MusicTagView.h; sourceTree = "<group>"; };
 		BC3A4EB628DAFCF7001C4428 /* MusicTagView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MusicTagView.m; sourceTree = "<group>"; };
 		BC3ACD922890D60800060E97 /* FreezeListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FreezeListViewController.h; sourceTree = "<group>"; };
@@ -3092,6 +3104,26 @@
 		BCC0F7022A8CF13D00C4EFA4 /* TXDanMuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TXDanMuView.m; sourceTree = "<group>"; };
 		BCC305F628FD4C0800C39762 /* KSChatUserDetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSChatUserDetailViewController.h; sourceTree = "<group>"; };
 		BCC305F728FD4C0800C39762 /* KSChatUserDetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSChatUserDetailViewController.m; sourceTree = "<group>"; };
+		BCC408CB2AFCE0B600C60249 /* KSVideoCropViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSVideoCropViewController.h; sourceTree = "<group>"; };
+		BCC408CC2AFCE0B600C60249 /* KSVideoCropViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSVideoCropViewController.m; sourceTree = "<group>"; };
+		BCC408CE2AFCE0D500C60249 /* KSCropImageNavView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSCropImageNavView.h; sourceTree = "<group>"; };
+		BCC408CF2AFCE0D600C60249 /* KSCropImageNavView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = KSCropImageNavView.xib; sourceTree = "<group>"; };
+		BCC408D02AFCE0D600C60249 /* VideoCropImageViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoCropImageViewCell.m; sourceTree = "<group>"; };
+		BCC408D12AFCE0D600C60249 /* KSVideoImageSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSVideoImageSlider.m; sourceTree = "<group>"; };
+		BCC408D22AFCE0D600C60249 /* KSCropImageNavView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KSCropImageNavView.m; sourceTree = "<group>"; };
+		BCC408D32AFCE0D600C60249 /* VideoCropImageViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VideoCropImageViewCell.xib; sourceTree = "<group>"; };
+		BCC408D42AFCE0D700C60249 /* KSVideoImageSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KSVideoImageSlider.h; sourceTree = "<group>"; };
+		BCC408D52AFCE0D700C60249 /* VideoCropImageViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoCropImageViewCell.h; sourceTree = "<group>"; };
+		BCC408DB2AFCE11700C60249 /* MusicPublistAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MusicPublistAlert.m; sourceTree = "<group>"; };
+		BCC408DC2AFCE11700C60249 /* MusicPublicContentView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MusicPublicContentView.m; sourceTree = "<group>"; };
+		BCC408DD2AFCE11800C60249 /* MusicPublicContentView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MusicPublicContentView.xib; sourceTree = "<group>"; };
+		BCC408DE2AFCE11800C60249 /* MusicPublistAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicPublistAlert.h; sourceTree = "<group>"; };
+		BCC408DF2AFCE11800C60249 /* VideoCoverChooseView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VideoCoverChooseView.xib; sourceTree = "<group>"; };
+		BCC408E02AFCE11800C60249 /* MusicPublistAlert.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MusicPublistAlert.xib; sourceTree = "<group>"; };
+		BCC408E12AFCE11900C60249 /* MusicPubHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicPubHeader.h; sourceTree = "<group>"; };
+		BCC408E22AFCE11900C60249 /* VideoCoverChooseView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoCoverChooseView.h; sourceTree = "<group>"; };
+		BCC408E32AFCE11900C60249 /* VideoCoverChooseView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoCoverChooseView.m; sourceTree = "<group>"; };
+		BCC408E42AFCE11900C60249 /* MusicPublicContentView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MusicPublicContentView.h; sourceTree = "<group>"; };
 		BCC583D528A9FA8100BAB4CF /* cloud_animation_9.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cloud_animation_9.png; sourceTree = "<group>"; };
 		BCC583D628A9FA8100BAB4CF /* cloud_animation_8.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cloud_animation_8.png; sourceTree = "<group>"; };
 		BCC583D728A9FA8100BAB4CF /* cloud_animation_20.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = cloud_animation_20.png; sourceTree = "<group>"; };
@@ -5935,9 +5967,6 @@
 				BC38C4182AF900E100ABFCC2 /* KSPlayerSliderView.xib */,
 				BC38C4132AF900E100ABFCC2 /* KSPlayerView.h */,
 				BC38C4012AF900E100ABFCC2 /* KSPlayerView.m */,
-				BC38C4042AF900E100ABFCC2 /* MusicPublistAlert.h */,
-				BC38C40D2AF900E100ABFCC2 /* MusicPublistAlert.m */,
-				BC38C4152AF900E100ABFCC2 /* MusicPublistAlert.xib */,
 				BC38C40E2AF900E100ABFCC2 /* UIView+KSCovertImage.h */,
 				BC38C4022AF900E100ABFCC2 /* UIView+KSCovertImage.m */,
 				BC38C40A2AF900E100ABFCC2 /* VideoPlayerView */,
@@ -5994,10 +6023,12 @@
 		BC38C4652AFA1F4B00ABFCC2 /* Controller */ = {
 			isa = PBXGroup;
 			children = (
+				BC38C4682AFA1F4B00ABFCC2 /* KSDraftMergeViewController.h */,
 				BC38C4662AFA1F4B00ABFCC2 /* KSDraftMergeViewController.m */,
 				BC38C4672AFA1F4B00ABFCC2 /* MineWorksViewController.h */,
-				BC38C4682AFA1F4B00ABFCC2 /* KSDraftMergeViewController.h */,
 				BC38C4692AFA1F4B00ABFCC2 /* MineWorksViewController.m */,
+				BCC408CB2AFCE0B600C60249 /* KSVideoCropViewController.h */,
+				BCC408CC2AFCE0B600C60249 /* KSVideoCropViewController.m */,
 			);
 			path = Controller;
 			sourceTree = "<group>";
@@ -6028,6 +6059,24 @@
 				BC38C4712AFA1F4B00ABFCC2 /* MineWorksOpenDisplayCell.h */,
 				BC38C4742AFA1F4B00ABFCC2 /* MineWorksOpenDisplayCell.m */,
 				BC38C4752AFA1F4B00ABFCC2 /* MineWorksOpenDisplayCell.xib */,
+				BCC408CE2AFCE0D500C60249 /* KSCropImageNavView.h */,
+				BCC408D22AFCE0D600C60249 /* KSCropImageNavView.m */,
+				BCC408CF2AFCE0D600C60249 /* KSCropImageNavView.xib */,
+				BCC408D42AFCE0D700C60249 /* KSVideoImageSlider.h */,
+				BCC408D12AFCE0D600C60249 /* KSVideoImageSlider.m */,
+				BCC408D52AFCE0D700C60249 /* VideoCropImageViewCell.h */,
+				BCC408D02AFCE0D600C60249 /* VideoCropImageViewCell.m */,
+				BCC408D32AFCE0D600C60249 /* VideoCropImageViewCell.xib */,
+				BCC408E12AFCE11900C60249 /* MusicPubHeader.h */,
+				BCC408E42AFCE11900C60249 /* MusicPublicContentView.h */,
+				BCC408DC2AFCE11700C60249 /* MusicPublicContentView.m */,
+				BCC408DD2AFCE11800C60249 /* MusicPublicContentView.xib */,
+				BCC408DE2AFCE11800C60249 /* MusicPublistAlert.h */,
+				BCC408DB2AFCE11700C60249 /* MusicPublistAlert.m */,
+				BCC408E02AFCE11800C60249 /* MusicPublistAlert.xib */,
+				BCC408E22AFCE11900C60249 /* VideoCoverChooseView.h */,
+				BCC408E32AFCE11900C60249 /* VideoCoverChooseView.m */,
+				BCC408DF2AFCE11800C60249 /* VideoCoverChooseView.xib */,
 			);
 			path = View;
 			sourceTree = "<group>";
@@ -7348,6 +7397,9 @@
 				BC9AA0D32ABC430B00CD954D /* KSCustomLoadingView.h */,
 				BC9AA0D22ABC430A00CD954D /* KSCustomLoadingView.m */,
 				BC9AA0D12ABC430A00CD954D /* KSCustomLoadingView.xib */,
+				BC38C49A2AFA4C7C00ABFCC2 /* KSProgressLoadingView.h */,
+				BC38C49C2AFA4C7D00ABFCC2 /* KSProgressLoadingView.m */,
+				BC38C49B2AFA4C7C00ABFCC2 /* KSProgressLoadingView.xib */,
 			);
 			name = LoadingManager;
 			path = KulexiuForTeacher/Common/LoadingManager;
@@ -8163,6 +8215,7 @@
 				BC41104F280678ED00800BD9 /* HomeworkSortView.xib in Resources */,
 				275FA56427F31AEE00EB6240 /* MinePageHeadView.xib in Resources */,
 				BC71D294288811BF0010F14B /* tabbar5.json in Resources */,
+				BCC408E72AFCE11900C60249 /* MusicPublicContentView.xib in Resources */,
 				BC56C97529238CC300AF301F /* CoursewareAlertView.xib in Resources */,
 				BCC583F528A9FA8100BAB4CF /* cloud_animation_8.png in Resources */,
 				BCDF820C2A8A2955005F8B82 /* ClassMemberSettingView.xib in Resources */,
@@ -8198,6 +8251,7 @@
 				BC02BCEC28B324FE005CB483 /* LiveMemberSeatCell.xib in Resources */,
 				27F9030127E864AE00C08A19 /* NetworkBodyView.xib in Resources */,
 				BCB14112288A49710022C13A /* HomeButtonView.xib in Resources */,
+				BC38C49D2AFA4C7D00ABFCC2 /* KSProgressLoadingView.xib in Resources */,
 				BC4BCE7F2823B66A00522C8B /* AddressDetailBodyView.xib in Resources */,
 				BC513E7A28A4D85F003F58C4 /* accomapny_animation.json in Resources */,
 				BCD457B62865651A0010B493 /* LiveMoreDisplayView.xib in Resources */,
@@ -8210,6 +8264,7 @@
 				BC3673DE28A606A500059721 /* musicRoom_animation_1.png in Resources */,
 				BC1553532AB3279500C1C347 /* TenentGroupAddMemberCell.xib in Resources */,
 				BCC0F7062A8CF13D00C4EFA4 /* TXDanBottomView.xib in Resources */,
+				BCC408E92AFCE11900C60249 /* MusicPublistAlert.xib in Resources */,
 				2780C92927E490CA00A95A4F /* VefiBodyView.xib in Resources */,
 				BCC5840828A9FA8100BAB4CF /* cloud_animation_10.png in Resources */,
 				BCA9CE4427FD947C00D558C6 /* AccompanyArrangeCell.xib in Resources */,
@@ -8288,6 +8343,7 @@
 				27F9030827E86CCB00C08A19 /* DeviceCheckView.xib in Resources */,
 				BC71D1FA2887FDD40010F14B /* img_14.png in Resources */,
 				BC523B1228A09F3800E9D66B /* MineHeadView.xib in Resources */,
+				BCC408D62AFCE0D700C60249 /* KSCropImageNavView.xib in Resources */,
 				BC3673DC28A606A500059721 /* musicRoom_animation_0.png in Resources */,
 				275B16F127EAF9DD0081FDEF /* ChatNavView.xib in Resources */,
 				2773205327EDB75B008FAECA /* GroupNoticeCell.xib in Resources */,
@@ -8350,6 +8406,7 @@
 				BC14E48E2AB2FBCD000C4983 /* TenantUnbindDetailBodyView.xib in Resources */,
 				BC513E7E28A4D874003F58C4 /* live_animation.json in Resources */,
 				BC106BA32A8F45AA000759A9 /* TXLiveRoomHeadView.xib in Resources */,
+				BCC408DA2AFCE0D700C60249 /* VideoCropImageViewCell.xib in Resources */,
 				27D83F5927F4225D00062476 /* LivePreviewBodyView.xib in Resources */,
 				BC41104A2806706800800BD9 /* HomeworkListCell.xib in Resources */,
 				BCD457A72863196F0010B493 /* CourseTimeSegView.xib in Resources */,
@@ -8359,13 +8416,13 @@
 				2779362E27E33C360010E277 /* LoginBodyView.xib in Resources */,
 				BC84182D2AC2D82900D8F90E /* ForgetPasswordBodyView.xib in Resources */,
 				BC8B6E6E285836B600866917 /* low_staff.png in Resources */,
+				BCC408E82AFCE11900C60249 /* VideoCoverChooseView.xib in Resources */,
 				BCB399BD27F9831D00AFF376 /* CourseForLiveCell.xib in Resources */,
 				2723B68927F1643B00E0B90B /* HomeBodyView.xib in Resources */,
 				BCFE541A2817BE0800AD6786 /* IncomeHeaderView.xib in Resources */,
 				BC71D1F32887FDD40010F14B /* img_7.png in Resources */,
 				BCE6A0A527F8517900C97704 /* MineVideoCell.xib in Resources */,
 				BCC9F40727F69BD200647449 /* SealClass.strings in Resources */,
-				BC38C42C2AF900E100ABFCC2 /* MusicPublistAlert.xib in Resources */,
 				BCD6D16C28195FC5009A773E /* CashRecordHeadView.xib in Resources */,
 				BC5EB5AB2803D86500B4A3B0 /* AccompanyAlertView.xib in Resources */,
 				BCE6A08C27F823A300C97704 /* AccompanyCourseCell.xib in Resources */,
@@ -8611,7 +8668,6 @@
 				BCED5CB128507E85009A42DE /* KSChatMusicMessage.m in Sources */,
 				BCA9CE3927FD93EB00D558C6 /* AccompanyStudentEvaCell.m in Sources */,
 				2779324027E30FC30010E277 /* VoNetworking+RequestManager.m in Sources */,
-				BC38C4282AF900E100ABFCC2 /* MusicPublistAlert.m in Sources */,
 				2723B68C27F1685600E0B90B /* HomeNavView.m in Sources */,
 				BC12638D28FEB5E600509E90 /* RecentPracticeModel.m in Sources */,
 				27BC3B2927F2DB8600D81E30 /* MusicUploadView.m in Sources */,
@@ -8805,9 +8861,11 @@
 				27F902F127E8614D00C08A19 /* SettingViewController.m in Sources */,
 				BC38C4322AF900E100ABFCC2 /* kSNewPlayer.m in Sources */,
 				BCF61BE128041FC90000ACFE /* UIView+ExtensionForDotLine.m in Sources */,
+				BCC408EA2AFCE11900C60249 /* VideoCoverChooseView.m in Sources */,
 				BC71DE9B2A89F450003F165E /* TXClassroomViewController.m in Sources */,
 				BCC9F42F27F69BD200647449 /* HTTPUtility.m in Sources */,
 				BC56C97C2923A3FD00AF301F /* CoursewareAlertCell.m in Sources */,
+				BCC408E52AFCE11900C60249 /* MusicPublistAlert.m in Sources */,
 				275E3DE227F467410010EC30 /* KSChatEmojiCollectionCell.m in Sources */,
 				BC14E4952AB31059000C4983 /* TenantCreateGroupBodyView.m in Sources */,
 				BCA1134828A22A66007FAFB9 /* HomeHotMusicCollectionCell.m in Sources */,
@@ -8816,6 +8874,7 @@
 				BC84182F2AC2D82900D8F90E /* ForgetPasswordBodyView.m in Sources */,
 				BC8831002873D26000C702A0 /* LiveVideoModel.m in Sources */,
 				BC1365C8280D476500EB03E2 /* NotiferMessageCell.m in Sources */,
+				BCC408D92AFCE0D700C60249 /* KSCropImageNavView.m in Sources */,
 				27F9030E27E875DD00C08A19 /* AudioPlayManager.m in Sources */,
 				BC000D9E2A84E68B006C5A89 /* KSTXGroupChatViewController.m in Sources */,
 				277935E227E327F00010E277 /* KSTabBarViewController.m in Sources */,
@@ -8979,6 +9038,7 @@
 				2779360C27E32BE50010E277 /* LoginViewController.m in Sources */,
 				BC84183A2AC2D83700D8F90E /* NewPwdModifyViewController.m in Sources */,
 				27F9CB0E27EC5DF5003E0FE4 /* KSRCloudMediaManager.m in Sources */,
+				BC38C49E2AFA4C7D00ABFCC2 /* KSProgressLoadingView.m in Sources */,
 				BC221FB928C8687300F99802 /* MusicSortView.m in Sources */,
 				BC4BCE7D2823B66000522C8B /* AddressDetailBodyView.m in Sources */,
 				BC38C4222AF900E100ABFCC2 /* KSPlayerView.m in Sources */,
@@ -9037,6 +9097,7 @@
 				BC71D1A62887FDAC0010F14B /* LaunchAnimationViewController.m in Sources */,
 				277931CC27E30FC20010E277 /* KSGifRefreshFooter.m in Sources */,
 				2779321127E30FC30010E277 /* YKMultiLevelTableView.m in Sources */,
+				BCC408D82AFCE0D700C60249 /* KSVideoImageSlider.m in Sources */,
 				BC523B1028A09F3000E9D66B /* MineHeadView.m in Sources */,
 				BCF1BA5127F5C4DD00FA36C4 /* KSLiveChatroomMemberCount.m in Sources */,
 				BCDF82292A8A3080005F8B82 /* ZoomControl.m in Sources */,
@@ -9099,6 +9160,7 @@
 				277931D727E30FC20010E277 /* UIImage+ResizeImage.m in Sources */,
 				BC000DA12A84E6D5006C5A89 /* KSTXC2CChatViewController.m in Sources */,
 				BC71DF002A89F470003F165E /* MainDisplayView.m in Sources */,
+				BCC408E62AFCE11900C60249 /* MusicPublicContentView.m in Sources */,
 				BC7CFFA92817E3BD00CAEB21 /* IncomeCountTopView.m in Sources */,
 				2779329927E30FEB0010E277 /* MSSBrowseActionSheetCell.m in Sources */,
 				BC965AE82925D1D700AB90B0 /* ClassroomCoursewarePlayView.m in Sources */,
@@ -9131,6 +9193,7 @@
 				2779320627E30FC30010E277 /* UIView+ValueAdd.m in Sources */,
 				BCA9CE1527FD339400D558C6 /* AuthDisplayView.m in Sources */,
 				2779329B27E30FEB0010E277 /* UIView+MSSLayout.m in Sources */,
+				BCC408CD2AFCE0B700C60249 /* KSVideoCropViewController.m in Sources */,
 				BC38C4822AFA1F4B00ABFCC2 /* MineWorksNavView.m in Sources */,
 				2779322B27E30FC30010E277 /* ALCalendarConfig.m in Sources */,
 				BC5E4B18291E5E26001BBCD2 /* WidgetViewController.m in Sources */,
@@ -9303,6 +9366,7 @@
 				BC38C4832AFA1F4B00ABFCC2 /* MineWorksDraftsCell.m in Sources */,
 				277931E227E30FC20010E277 /* UIViewController+zhStatusBarStyle.m in Sources */,
 				BC71DF0B2A89F470003F165E /* TXMainToolView.m in Sources */,
+				BCC408D72AFCE0D700C60249 /* VideoCropImageViewCell.m in Sources */,
 				275E3DFA27F46B340010EC30 /* KSBeautySettingView.m in Sources */,
 				BC41104528066EF200800BD9 /* EvaluateCourseBodyView.m in Sources */,
 				2779328E27E30FEB0010E277 /* MSSBrowseLoadingImageView.m in Sources */,

+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_choose_image.imageset/Contents.json

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

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_choose_image.imageset/cover_choose_image@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_choose_image.imageset/cover_choose_image@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_crop_image.imageset/Contents.json

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

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_crop_image.imageset/cover_crop_image@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/cover_crop_image.imageset/cover_crop_image@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/minework_Line.imageset/Contents.json

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

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/minework_Line.imageset/minework_Line@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/minework_Line.imageset/minework_Line@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/Contents.json

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

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/progressLoading_bg@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progressLoading_bg.imageset/progressLoading_bg@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progress_dot.imageset/Contents.json

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

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progress_dot.imageset/progress_dot@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/progress_dot.imageset/progress_dot@3x.png


+ 22 - 0
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/Contents.json

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

BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/videoMerge_cover@2x.png


BIN
KulexiuForTeacher/KulexiuForTeacher/Assets.xcassets/PlayerImage/videoMerge_cover.imageset/videoMerge_cover@3x.png


+ 54 - 33
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSAccompanyWebViewController.m

@@ -406,27 +406,31 @@
 
 - (void)viewWillDisappear:(BOOL)animated {
     [super viewWillDisappear:animated];
-    if (_AQManager) {
-        [_AQManager freeAudioQueue];
-        _AQManager = nil;
-    }
+    
     if (_socketManager) {
         [self.socketManager SRWebSocketClose];
         _socketManager = nil;
     }
-    // 返回不保存视频
-    [self ignorRecordVideo];
+    // 停止播放和录制
     [self stopSession];
-    
-    // 如果退出评测页面 清除 playerEngine
-    if (self.playerEngine) {
-        [self.playerEngine cleanup];
-        self.playerEngine = nil;
-    }
+    [self stopPlayAction];
+    [self stopRecordService];
     [self stopTuner];
+    
     BOOL isBack = [self isViewPopDismiss];
-    if (isBack) {
-         [self freeMp3Player];
+    if (isBack) { // 页面销毁才删除
+        if (_AQManager) {
+            [_AQManager freeAudioQueue];
+            _AQManager = nil;
+        }
+        // 如果退出评测页面 清除 playerEngine
+        if (self.playerEngine) {
+            [self.playerEngine cleanup];
+            self.playerEngine = nil;
+        }
+        // 返回不保存视频
+        [self ignorRecordVideo];
+        [self freeMp3Player];
     }
 }
 
@@ -546,6 +550,7 @@
                 [self postMessage:parm];
             }
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"startCapture"]) { // 开始录制
+                NSLog(@"------ startCapture ");
                 // 需要合成音频
                 [self.videoRecordManager setIgnoreAudio:YES];
                 self.videoRecordManager.audioUrl = self.AQManager.audioUrl;
@@ -553,6 +558,8 @@
                 [self postMessage:parm];
             }
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"endCapture"]) { // 结束录制
+                NSLog(@"------ endCapture ");
+
                 if (self->_videoRecordManager) {
                     self.endRecordParm = parm;
                     [self.videoRecordManager stopRecord];
@@ -811,6 +818,7 @@
                     NSString *fileName = [[accompanyUrl componentsSeparatedByString:@"/"] lastObject];
                     NSString *filePath = [self getAccompanyFilePathWithName:fileName];
                     NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:filePath];
+                    self.accompanyUrl = accompanyUrl;
                     if ([self checkSongHasSaveAccompanyWithSongUrl:accompanyUrl]) {
                         [self configVideoRecord:fileUrl];
                     }
@@ -902,21 +910,25 @@
             // 音视频合成
             else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"openAdjustRecording"]) {
                 KSMediaMergeView *mergeView = [[KSMediaMergeView alloc] init];
-                [self.view addSubview:mergeView];
-                [mergeView mas_makeConstraints:^(MASConstraintMaker *make) {
-                    make.left.right.top.bottom.mas_equalTo(self.view);
-                }];
-                NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
-                mergeView.recordId = [content ks_stringValueForKey:@"recordId"];
-                mergeView.songName = [content ks_stringValueForKey:@"title"];
-                mergeView.coverImage = [content ks_stringValueForKey:@"coverImg"];
-                if (self.AQManager) {
+                
+                if (self.AQManager && self.AQManager.audioUrl) {
                     self.recordUrl = self.AQManager.audioUrl;
+                    [self.view addSubview:mergeView];
+                    [mergeView mas_makeConstraints:^(MASConstraintMaker *make) {
+                        make.left.right.top.bottom.mas_equalTo(self.view);
+                    }];
+                    NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
+                    mergeView.recordId = [content ks_stringValueForKey:@"recordId"];
+                    mergeView.songName = [content ks_stringValueForKey:@"title"];
+                    mergeView.coverImage = [content ks_stringValueForKey:@"coverImg"];
+                    MJWeakSelf;
+                    [mergeView configWithVideoUrl:self.videoRecordManager.videoFileURL bgAudioUrl:self.bgAudioUrl remoteBgUrl:self.accompanyUrl  recordUrl:self.recordUrl offsetTime:self.offsetTime mergeCallback:^{
+                        [weakSelf musicPublishCallBack:content];
+                    }];
+                }
+                else {
+                    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"麦克风被占用"];
                 }
-                MJWeakSelf;
-                [mergeView configWithVideoUrl:self.videoRecordManager.videoFileURL bgAudioUrl:self.bgAudioUrl remoteBgUrl:self.accompanyUrl  recordUrl:self.recordUrl offsetTime:self.offsetTime mergeCallback:^{
-                    [weakSelf musicPublishCallBack:content];
-                }];
             }
             else {
                 [super handleScriptMessageSource:parm];
@@ -932,6 +944,7 @@
     [parm setValue:@{} forKey:@"content"];
     [self postMessage:parm];
 }
+
 - (void)uploadVideoWithParm:(NSMutableDictionary *)contentParm sendParm:(NSMutableDictionary *)sendParm {
     MJWeakSelf;
     [self.videoRecordManager uploadRecordVideoSuccess:^(NSString * _Nonnull videoUrl) {
@@ -979,6 +992,7 @@
 
 - (void)configVideoRecord:(NSURL *)path {
     self.videoRecordManager.bgAudioUrl = path;
+    self.bgAudioUrl = path;
 }
 
 
@@ -1324,7 +1338,9 @@
 }
 
 - (void)showSuccessMessage:(NSString *)message {
-    [LOADING_MANAGER MBShowAUTOHidingInWindow:message];
+    if (![NSString isEmptyString:message]) {
+        [LOADING_MANAGER MBShowAUTOHidingInWindow:message];
+    }
     // 成功
     if (self.endRecordParm) {
         [self postMessage:self.endRecordParm];
@@ -1438,17 +1454,22 @@
 
 #pragma mark ----- 播放控制
 - (void)playAction {
-    self.isPlaying = YES;
-    [self.playerEngine playMIDIFile];
+    if (self.playerEngine) {
+        self.isPlaying = YES;
+        [self.playerEngine playMIDIFile];
+    }
 }
 
 - (void)stopPlayAction {
-    self.isPlaying = NO;
-    if ([self.playerEngine isPlayingFile]) {
-        [self.playerEngine stopPlayingMIDIFile];
+    if (self.playerEngine) {
+        self.isPlaying = NO;
+        if ([self.playerEngine isPlayingFile]) {
+            [self.playerEngine stopPlayingMIDIFile];
+        }
     }
 }
 
+
 #pragma mark ----- 小酷AI loading
 - (AccompanyLoadingView *)loadingView {
     if (!_loadingView) {

+ 192 - 71
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSBaseWKWebViewController.m

@@ -29,6 +29,7 @@
 #import "KSEnterLiveroomManager.h"
 #import "KSWebLoadRefreshView.h"
 #import "UserInfoManager.h"
+#import "KSVideoCropViewController.h"
 
 typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     CHOOSETYPE_XML,
@@ -37,7 +38,7 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     CHOOSETYPE_ALL,
 };
 
-@interface KSBaseWKWebViewController ()<UIDocumentPickerDelegate>
+@interface KSBaseWKWebViewController ()<UIDocumentPickerDelegate,UIDocumentInteractionControllerDelegate>
 
 @property (nonatomic, assign) BOOL isOutLink;  // 外部链接
 
@@ -68,6 +69,8 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
 
 @property (nonatomic, strong) KSUMShareManager *shareManager;
 
+@property (nonatomic, assign) BOOL isDownloadFile;
+
 @end
 
 @implementation KSBaseWKWebViewController
@@ -186,10 +189,15 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
         }
     }
     else {
-        KSBaseViewController *nextCtrl = [self getNextViewController];
-        if (nextCtrl) {
-            if (nextCtrl.ks_landScape != self.ks_landScape) {
-                [self changeOrientation:NO];
+        if ([self.presentedViewController isKindOfClass:NSClassFromString(@"TZImagePickerController")] || [self.presentedViewController isKindOfClass:NSClassFromString(@"RSKImageCropViewController")] || [self.presentedViewController isKindOfClass:NSClassFromString(@"KSVideoCropViewController")]) {
+            NSLog(@"-----");
+        }
+        else {
+            KSBaseViewController *nextCtrl = [self getNextViewController];
+            if (nextCtrl) {
+                if (nextCtrl.ks_landScape != self.ks_landScape) {
+                    [self changeOrientation:NO];
+                }
             }
         }
     }
@@ -608,9 +616,97 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"shareTripartite"]) { // 分享到微信
         [self shareToWeChat:parm];
     }
+    else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"saveFile"]) { // 下载资源
+        NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
+
+        NSString *url = [content ks_stringValueForKey:@"url"];
+        [self downFile:url];
+    }
+    else if ([[parm ks_stringValueForKey:@"api"] isEqualToString:@"videoCrop"]) { // 选择封面
+        NSDictionary *content = [parm ks_dictionaryValueForKey:@"content"];
+        KSVideoCropViewController *ctrl = [[KSVideoCropViewController alloc] init];
+        NSString *videoUrl = [content ks_stringValueForKey:@"url"];
+        [ctrl configWithVideoRemoteUrl:videoUrl];
+        [ctrl changeLandScape];
+        MJWeakSelf;
+        [ctrl chooseCropImageCallback:^(UIImage * _Nonnull cropImage) {
+            [weakSelf videCropImage:cropImage content:content];
+        }];
+        ctrl.modalPresentationStyle = UIModalPresentationFullScreen;
+        [self.navigationController presentViewController:ctrl animated:YES completion:nil];
+    }
 }
 
+- (void)videCropImage:(UIImage *)cover content:(NSDictionary *)content {
+    NSData *imgData = [UIImage turnsImaegDataByImage:cover];
+    NSString *fileName = @"videoCoverImage";
 
+    [LOADING_MANAGER showCustomLoading:@"上传中..."];
+    [UPLOAD_MANAGER configBucketName:@"klx"];
+    [UPLOAD_MANAGER uploadFile:imgData fileName:fileName fileSuffix:[UIImage typeForImageData:imgData] progress:^(int64_t bytesWritten, int64_t totalBytes) {
+        // 显示进度
+        int progress = (int)(bytesWritten / totalBytes * 100);
+        __block NSString *tipsMessage = [NSString stringWithFormat:@"上传中 %d%%",progress];
+        dispatch_main_async_safe(^{
+            [LOADING_MANAGER.loadingView setDisplayText:tipsMessage];
+        });
+    } successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
+        [LOADING_MANAGER removeCustomLoading];
+        NSString *fileUrl = [fileUrlArray lastObject];
+        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:content];
+        [content setValue:fileUrl forKey:@"videoCover"];
+        NSMutableDictionary *sendParm = [NSMutableDictionary dictionary];
+        [sendParm setValue:@"videoCrop" forKey:@"api"];
+        [sendParm setValue:dic forKey:@"content"];
+        [self postMessage:sendParm];
+    } faliure:^(NSError * _Nullable error, NSString * _Nullable descMessaeg) {
+        [LOADING_MANAGER removeCustomLoading];
+    }];
+}
+
+- (void)downFile:(NSString *)fileUrl {
+    [LOADING_MANAGER showCustomLoading:@"文件下载中..."];
+    [KSNetworkingManager downloadFileRequestWithFileUrl:fileUrl progress:^(int64_t bytesRead, int64_t totalBytes) {
+        
+    } success:^(NSURL * _Nonnull fileUrl) {
+        [LOADING_MANAGER removeCustomLoading];
+        [self saveFileWithUrl:fileUrl];
+    } faliure:^(NSError * _Nonnull error) {
+        [LOADING_MANAGER removeCustomLoading];
+        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"下载失败"];
+    }];
+}
+
+- (void)saveFileWithUrl:(NSURL *)fileUrl {
+    if ([fileUrl.absoluteString hasSuffix:@".mp4"]) { // 视频
+        [LOADING_MANAGER showCustomLoading:@"视频保存中..."];
+        [[TZImageManager manager] saveVideoWithUrl:fileUrl completion:^(PHAsset *asset, NSError *error) {
+            if (!error) {
+                dispatch_main_async_safe(^{
+                    [LOADING_MANAGER removeCustomLoading];
+                    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"视频已保存到相册"];
+                });
+            }
+            else {
+                dispatch_main_async_safe(^{
+                    [LOADING_MANAGER removeCustomLoading];
+                    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"保存视频错误"];
+                });
+            }
+        }];
+    }
+    else { // 音频
+        [self saveFileToPhone:fileUrl];
+    }
+}
+
+- (void)saveFileToPhone:(NSURL *)fileUrl {
+    self.isDownloadFile = YES;
+    UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithURL:fileUrl inMode:UIDocumentPickerModeExportToService];
+    documentPicker.delegate = self;
+    documentPicker.modalPresentationStyle = UIModalPresentationFormSheet;
+    [self presentViewController:documentPicker animated:YES completion:nil];
+}
 - (void)joinLiveRoomWithRoomId:(NSString *)roomId {
     [KSEnterLiveroomManager queryLiveStatusConfig:roomId liveContent:nil inController:(CustomNavViewController *)self.navigationController callback:^(ENTER_CALLTYPE type) {
         
@@ -1255,7 +1351,12 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
 
 #pragma mark ---- UIDocumentPickerDelegate
 - (void)documentPickerWasCancelled:(UIDocumentPickerViewController *)controller {
-    [self fileChooseErrorCallback];
+    if (self.isDownloadFile) {
+        self.isDownloadFile = NO;
+    }
+    else {
+        [self fileChooseErrorCallback];
+    }
 }
 
 - (void)fileChooseErrorCallback {
@@ -1266,71 +1367,7 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     }
 }
 
-- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
-    NSArray *array = [[url absoluteString] componentsSeparatedByString:@"/"];
-    NSString *fileName = [array lastObject];
-    fileName = [fileName stringByRemovingPercentEncoding];
-    
-    if (self.fileChooseType == CHOOSETYPE_XML) {
-        if (![fileName hasSuffix:@".xml"]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传XML格式文件"];
-            [self fileChooseErrorCallback];
-            return;
-        }
-    }
-    else if (self.fileChooseType == CHOOSETYPE_MIDI) {
-        if (![fileName hasSuffix:@".mid"] || [fileName hasSuffix:@".midi"]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传mid格式文件"];
-            [self fileChooseErrorCallback];
-            return;
-        }
-    }
-    else if (self.fileChooseType == CHOOSETYPE_MP3) {
-        if (![fileName hasSuffix:@".mp3"]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传mp3格式文件"];
-            [self fileChooseErrorCallback];
-            return;
-        }
-    }
-    else {
-        if (![fileName hasSuffix:@".mp3"] && ![fileName hasSuffix:@".aac"]) {
-            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"暂不支持此格式!"];
-            [self fileChooseErrorCallback];
-            return;
-        }
-    }
-    
-    __block NSString * fileUrl = @"";
-    if ([KSICloudManager iCloudEnable]) {
-        [KSICloudManager downloadWithDocumentURL:url callBack:^(id obj) {
-            NSData *data = obj;
-            
-            //写入沙盒Documents
-             NSString *pathStr = [NSHomeDirectory() stringByAppendingString:[NSString stringWithFormat:@"/Documents/%@",fileName]];
-            [data writeToFile:pathStr atomically:YES];
-            
-            if (![[NSFileManager defaultManager] fileExistsAtPath:pathStr]) {
-                BOOL isSuccess = [data writeToFile:pathStr atomically:YES];
-                if (isSuccess) {
-                    fileUrl = pathStr;
-                }
-                else {
-                    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"写入文件错误!"];
-                    [self fileChooseErrorCallback];
-                }
-            }
-            else {
-                fileUrl = pathStr;
-            }
-            [self uploadFile:fileName fileUrl:pathStr];
-            
-        }];
-    }
-    else {
-        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"iCloud不可用!"];
-        [self fileChooseErrorCallback];
-    }
-}
+
 
 - (void)uploadFile:(NSString *)fileName fileUrl:(NSString *)fileUrl {
     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
@@ -1403,6 +1440,90 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
     }
 }
 
+#pragma mark - UIDocumentInteractionControllerDelegate
+-(UIViewController*)documentInteractionControllerViewControllerForPreview:(UIDocumentInteractionController*)controller{
+    return self;
+}
+-(UIView*)documentInteractionControllerViewForPreview:(UIDocumentInteractionController*)controller {
+    return self.view;
+}
+-(CGRect)documentInteractionControllerRectForPreview:(UIDocumentInteractionController*)controller {
+    return self.view.frame;
+}
+#pragma mark - UIDocumentPickerDelegate
+- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls {
+    if (self.isDownloadFile) {
+        self.isDownloadFile = NO;
+        //保存成功
+       [LOADING_MANAGER MBShowAUTOHidingInWindow:@"保存成功"];
+    }
+    else {
+        NSURL *url =  [urls lastObject];
+        NSArray *array = [[url absoluteString] componentsSeparatedByString:@"/"];
+        NSString *fileName = [array lastObject];
+        fileName = [fileName stringByRemovingPercentEncoding];
+        
+        if (self.fileChooseType == CHOOSETYPE_XML) {
+            if (![fileName hasSuffix:@".xml"]) {
+                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传XML格式文件"];
+                [self fileChooseErrorCallback];
+                return;
+            }
+        }
+        else if (self.fileChooseType == CHOOSETYPE_MIDI) {
+            if (![fileName hasSuffix:@".mid"] || [fileName hasSuffix:@".midi"]) {
+                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传mid格式文件"];
+                [self fileChooseErrorCallback];
+                return;
+            }
+        }
+        else if (self.fileChooseType == CHOOSETYPE_MP3) {
+            if (![fileName hasSuffix:@".mp3"]) {
+                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"请上传mp3格式文件"];
+                [self fileChooseErrorCallback];
+                return;
+            }
+        }
+        else {
+            if (![fileName hasSuffix:@".mp3"] && ![fileName hasSuffix:@".aac"]) {
+                [LOADING_MANAGER MBShowAUTOHidingInWindow:@"暂不支持此格式!"];
+                [self fileChooseErrorCallback];
+                return;
+            }
+        }
+        
+        __block NSString * fileUrl = @"";
+        if ([KSICloudManager iCloudEnable]) {
+            [KSICloudManager downloadWithDocumentURL:url callBack:^(id obj) {
+                NSData *data = obj;
+                
+                //写入沙盒Documents
+                 NSString *pathStr = [NSHomeDirectory() stringByAppendingString:[NSString stringWithFormat:@"/Documents/%@",fileName]];
+                [data writeToFile:pathStr atomically:YES];
+                
+                if (![[NSFileManager defaultManager] fileExistsAtPath:pathStr]) {
+                    BOOL isSuccess = [data writeToFile:pathStr atomically:YES];
+                    if (isSuccess) {
+                        fileUrl = pathStr;
+                    }
+                    else {
+                        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"写入文件错误!"];
+                        [self fileChooseErrorCallback];
+                    }
+                }
+                else {
+                    fileUrl = pathStr;
+                }
+                [self uploadFile:fileName fileUrl:pathStr];
+                
+            }];
+        }
+        else {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:@"iCloud不可用!"];
+            [self fileChooseErrorCallback];
+        }
+    }
+}
 /*
 #pragma mark - Navigation
 

+ 2 - 1
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.h

@@ -1453,9 +1453,10 @@ NS_ASSUME_NONNULL_BEGIN
 /// @param desc 描述
 /// @param type 草稿 DRAFT 作品FORMAL,
 /// @param musicPracticeRecordId 云教练id
+/// @param videoImg 视频封面
 /// @param success 成功
 /// @param faliure 失败
-+ (void)saveMusicMessage:(NSString *)post jsonConfig:(NSString *)jsonConfig img:(NSString *)img videoUrl:(NSString *)videoUrl accompanyUrl:(NSString *)accompanyUrl desc:(NSString *)desc type:(NSString *)type musicPracticeRecordId:(NSString *)musicPracticeRecordId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
++ (void)saveMusicMessage:(NSString *)post jsonConfig:(NSString *)jsonConfig img:(NSString *)img videoUrl:(NSString *)videoUrl accompanyUrl:(NSString *)accompanyUrl desc:(NSString *)desc type:(NSString *)type musicPracticeRecordId:(NSString *)musicPracticeRecordId videoImg:(NSString *)videoImg success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure;
 
 // /userMusic/page
 

+ 3 - 1
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSNetworkingManager.m

@@ -2652,9 +2652,10 @@
 /// @param desc 描述
 /// @param type 草稿 DRAFT 作品FORMAL,
 /// @param musicPracticeRecordId 云教练id
+/// @param videoImg 视频封面
 /// @param success 成功
 /// @param faliure 失败
-+ (void)saveMusicMessage:(NSString *)post jsonConfig:(NSString *)jsonConfig img:(NSString *)img videoUrl:(NSString *)videoUrl accompanyUrl:(NSString *)accompanyUrl desc:(NSString *)desc type:(NSString *)type musicPracticeRecordId:(NSString *)musicPracticeRecordId success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
++ (void)saveMusicMessage:(NSString *)post jsonConfig:(NSString *)jsonConfig img:(NSString *)img videoUrl:(NSString *)videoUrl accompanyUrl:(NSString *)accompanyUrl desc:(NSString *)desc type:(NSString *)type musicPracticeRecordId:(NSString *)musicPracticeRecordId videoImg:(NSString *)videoImg success:(void(^)(NSDictionary *dic))success faliure:(void(^)(NSError *error))faliure {
     [self configRequestMethodJSON];
     NSString *url = [NSString stringWithFormat:@"%@%@", hostURL, @"/api-teacher/userMusic/save"];
     NSMutableDictionary *parm = [NSMutableDictionary dictionary];
@@ -2664,6 +2665,7 @@
     [parm setValue:accompanyUrl forKey:@"accompanyUrl"];
     [parm setValue:desc forKey:@"desc"];
     [parm setValue:type forKey:@"type"];
+    [parm setValue:videoImg forKey:@"videoImg"];
     [parm setValue:musicPracticeRecordId forKey:@"musicPracticeRecordId"];
     
     [self request:post andWithUrl:url and:parm success:success faliure:faliure];

+ 3 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Base/KSVideoRecordManager.m

@@ -306,6 +306,9 @@
     self.videoFileURL = outputFileURL;
     [self resetSession];
     self.skipSaveRecord = NO;
+    if (self.callback) {
+        self.callback(YES, @"");
+    }
 }
 
 - (void)saveVideoCallback:(KSVideoRecordCallback)callback {

+ 15 - 15
KulexiuForTeacher/KulexiuForTeacher/Common/Define/KSDomain.h

@@ -13,27 +13,27 @@
 //#ifdef DEBUG
 
 // 开发环境
-#define hostURL (@"https://dev.colexiu.com")
-#define SEALCLASSHOST (@"https://dev.colexiu.com/api-classroom")
-#define WEBHOST (@"https://dev.colexiu.com/teacher")
-#define SOCKET_URL (@"wss://dev.colexiu.com/audioAnalysis")
-#define JSPUSH_ENVIRONMENT (NO)
-#define RCIM_KEY (@"0vnjpoad0jbdz")
-#define SUBMIT_UUID (NO)
-#define CONFIG_TXSDKAPPID (1400805079)
-#define TXOfflinePushCertificateIDForAPNS (39559)
-
-// 测试环境
-//#define hostURL (@"https://test.colexiu.com")
-//#define SEALCLASSHOST (@"https://test.colexiu.com/api-classroom")
-//#define WEBHOST (@"https://test.colexiu.com/teacher")
-//#define SOCKET_URL (@"wss://test.colexiu.com/audioAnalysis")
+//#define hostURL (@"https://dev.colexiu.com")
+//#define SEALCLASSHOST (@"https://dev.colexiu.com/api-classroom")
+//#define WEBHOST (@"https://dev.colexiu.com/teacher")
+//#define SOCKET_URL (@"wss://dev.colexiu.com/audioAnalysis")
 //#define JSPUSH_ENVIRONMENT (NO)
 //#define RCIM_KEY (@"0vnjpoad0jbdz")
 //#define SUBMIT_UUID (NO)
 //#define CONFIG_TXSDKAPPID (1400805079)
 //#define TXOfflinePushCertificateIDForAPNS (39559)
 
+// 测试环境
+#define hostURL (@"https://test.colexiu.com")
+#define SEALCLASSHOST (@"https://test.colexiu.com/api-classroom")
+#define WEBHOST (@"https://test.colexiu.com/teacher")
+#define SOCKET_URL (@"wss://test.colexiu.com/audioAnalysis")
+#define JSPUSH_ENVIRONMENT (NO)
+#define RCIM_KEY (@"0vnjpoad0jbdz")
+#define SUBMIT_UUID (NO)
+#define CONFIG_TXSDKAPPID (1400805079)
+#define TXOfflinePushCertificateIDForAPNS (39559)
+
 // 预生产
 //#define hostURL (@"https://ponline.colexiu.com")
 //#define SEALCLASSHOST (@"https://ponline.colexiu.com/api-classroom")

+ 13 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/LoadingManager/KSHudLoagingManager.h

@@ -8,6 +8,7 @@
 #import <Foundation/Foundation.h>
 #import <MBProgressHUD/MBProgressHUD.h>
 #import "KSCustomLoadingView.h"
+#import "KSProgressLoadingView.h"
 
 #define LOADING_MANAGER ([KSHudLoagingManager shareInstance])
 
@@ -19,6 +20,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 @property (nonatomic, strong) KSCustomLoadingView *loadingView;
 
+@property (nonatomic, strong) KSProgressLoadingView *progressLoading;
+
 + (instancetype)shareInstance;
 
 - (void)showCustomLoading:(NSString *)text;
@@ -43,7 +46,17 @@ NS_ASSUME_NONNULL_BEGIN
 - (void)KSShowMsg:(NSString *)message inView:(UIView *)displayView promptCompletion:(void(^)(void))promptCompletion;
 // 提示后续操作
 - (void)KSShowMsg:(NSString *)message promptCompletion:(void(^)(void))promptCompletion;
+/// 加载进度loading
+/// - Parameters:
+///   - text: 文本
+///   - progress: 进度比例 0~100
+- (void)showProgressLoading:(NSString *)text progress:(NSInteger)progress;
+
+/// 移除进度loading
+- (void)removeProgressLoading;
 
+// 进度loading后续操作
+- (void)KSShowProgressMsg:(NSString *)message promptCompletion:(void(^)(void))promptCompletion;
 @end
 
 NS_ASSUME_NONNULL_END

+ 41 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/LoadingManager/KSHudLoagingManager.m

@@ -133,4 +133,45 @@
     }
     return _loadingView;
 }
+
+- (KSProgressLoadingView *)progressLoading {
+    if (!_progressLoading) {
+        _progressLoading = [KSProgressLoadingView shareInstance];
+    }
+    return _progressLoading;
+}
+
+/// 加载进度loading
+/// - Parameters:
+///   - text: 文本
+///   - progress: 进度比例 0~100
+- (void)showProgressLoading:(NSString *)text progress:(NSInteger)progress {
+    dispatch_main_async_safe(^{
+        [self.progressLoading configProgressWithText:text progress:progress];
+        [self.progressLoading showLoadingView];
+    });
+}
+
+/// 移除进度loading
+- (void)removeProgressLoading {
+    dispatch_delay_block(DISPATCH_TIME_NOW, (int64_t)(0.5f * NSEC_PER_SEC), ^{
+        [self.progressLoading hideLoadingView];
+    });
+}
+
+- (void)removeProgressLoadingNoDelay {
+    [self.progressLoading hideLoadingView];
+
+}
+
+// 进度loading后续操作
+- (void)KSShowProgressMsg:(NSString *)message promptCompletion:(void(^)(void))promptCompletion {
+    [self.progressLoading configProgressWithText:message progress:100];
+    
+    dispatch_delay_block(DISPATCH_TIME_NOW, (int64_t)(PROMPT_TIME * NSEC_PER_SEC), ^{
+        [self removeProgressLoadingNoDelay];
+        promptCompletion();
+    });
+
+}
 @end

+ 24 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/LoadingManager/KSProgressLoadingView.h

@@ -0,0 +1,24 @@
+//
+//  KSProgressLoadingView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/7.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSProgressLoadingView : UIView
+
+
++ (instancetype)shareInstance;
+
+- (void)configProgressWithText:(NSString *)tipsMessage progress:(NSInteger)progress;
+
+- (void)showLoadingView;
+
+- (void)hideLoadingView;
+@end
+
+NS_ASSUME_NONNULL_END

+ 89 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/LoadingManager/KSProgressLoadingView.m

@@ -0,0 +1,89 @@
+//
+//  KSProgressLoadingView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/7.
+//
+
+#import "KSProgressLoadingView.h"
+
+@interface KSProgressLoadingView ()
+@property (weak, nonatomic) IBOutlet UIView *progressView;
+@property (weak, nonatomic) IBOutlet UIImageView *progressFillImage;
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *imageWidth;
+
+@property (weak, nonatomic) IBOutlet UILabel *progressTipsLabel;
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leadingSpace;
+
+@property (nonatomic, assign) NSInteger progress;
+
+@end
+
+@implementation KSProgressLoadingView
+
++ (instancetype)shareInstance {
+    KSProgressLoadingView *view = [[[NSBundle mainBundle] loadNibNamed:@"KSProgressLoadingView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configProgressWithText:(NSString *)tipsMessage progress:(NSInteger)progress {
+    self.progressTipsLabel.text = tipsMessage;
+    NSInteger space = progress * 1.0 / 100 * 280;
+    self.progress = space;
+    [UIView animateWithDuration:0.3f animations:^{
+        self.leadingSpace.constant = space;
+    }];
+    
+}
+
+- (void)showLoadingView {
+    UIWindow *windows = [NSObject getKeyWindow];
+    [windows addSubview:self];
+    [self mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(windows);
+    }];
+}
+
+- (void)hideLoadingView {
+    [self removeFromSuperview];
+}
+
+- (void)setProgress:(NSInteger)progress {
+    _progress = progress;
+    CGFloat width = progress;
+    [self.progressFillImage setImage:[self createGradientImageWithColor:@[HexRGB(0x44F1D0),HexRGB(0x2DC7AA)] rect:CGRectMake(0, 0, width, 8) start:CGPointMake(0.41, 0) end:CGPointMake(0.41, 1)]];
+    self.imageWidth.constant = width;
+}
+
+- (UIImage *)createGradientImageWithColor:(NSArray *)colors rect:(CGRect)rect start:(CGPoint)start end:(CGPoint)end {
+    if (!colors.count || CGRectEqualToRect(rect, CGRectZero)) {
+        return nil;
+    }
+    CAGradientLayer *gradientLayer = [CAGradientLayer layer];
+    
+    gradientLayer.frame = rect;
+    gradientLayer.startPoint = start;
+    gradientLayer.endPoint = end;
+    NSMutableArray *mutColors = [NSMutableArray arrayWithCapacity:colors.count];
+    for (UIColor *color in colors) {
+        [mutColors addObject:(__bridge id)color.CGColor];
+    }
+    gradientLayer.colors = [NSArray arrayWithArray:mutColors];
+    
+    UIGraphicsBeginImageContextWithOptions(gradientLayer.frame.size, gradientLayer.opaque, 0);
+    [gradientLayer renderInContext:UIGraphicsGetCurrentContext()];
+    UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
+    UIGraphicsEndImageContext();
+    return outputImage;
+}
+
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 104 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/LoadingManager/KSProgressLoadingView.xib

@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="KSProgressLoadingView">
+            <rect key="frame" x="0.0" y="0.0" width="695" height="345"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view alpha="0.71999999999999997" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bF6-xd-1LF">
+                    <rect key="frame" x="189.66666666666663" y="146.66666666666666" width="316" height="52"/>
+                    <color key="backgroundColor" red="0.52941176470588236" green="0.52941176470588236" blue="0.52941176470588236" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="316" id="1wt-uU-3Zy"/>
+                        <constraint firstAttribute="height" constant="52" id="Sx2-oq-9c8"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="26"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SUI-Ti-MzO">
+                    <rect key="frame" x="207.66666666666663" y="166.66666666666666" width="280" height="8"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="dij-Zh-MfT">
+                            <rect key="frame" x="0.0" y="0.0" width="0.0" height="8"/>
+                            <constraints>
+                                <constraint firstAttribute="width" id="wgg-ol-s5w"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="4"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                    </subviews>
+                    <color key="backgroundColor" red="0.85490196078431369" green="0.85490196078431369" blue="0.85490196078431369" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="280" id="6W3-xW-Afz"/>
+                        <constraint firstItem="dij-Zh-MfT" firstAttribute="leading" secondItem="SUI-Ti-MzO" secondAttribute="leading" id="BFx-PL-EXX"/>
+                        <constraint firstAttribute="height" constant="8" id="Rxe-2I-dzd"/>
+                        <constraint firstAttribute="bottom" secondItem="dij-Zh-MfT" secondAttribute="bottom" id="Tb8-Rw-DUH"/>
+                        <constraint firstItem="dij-Zh-MfT" firstAttribute="top" secondItem="SUI-Ti-MzO" secondAttribute="top" id="w7a-wJ-zNa"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="4"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="progressLoading_bg" translatesAutoresizingMaskIntoConstraints="NO" id="lOs-av-owS">
+                    <rect key="frame" x="231.66666666666663" y="106.66666666666669" width="232" height="52"/>
+                </imageView>
+                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="progress_dot" translatesAutoresizingMaskIntoConstraints="NO" id="tfN-3g-Eip">
+                    <rect key="frame" x="188" y="149.66666666666666" width="39" height="42"/>
+                </imageView>
+                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Rev-2X-b5J">
+                    <rect key="frame" x="347.66666666666669" y="210.66666666666666" width="0.0" height="20"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="20" id="heZ-tG-3dI"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <nil key="highlightedColor"/>
+                </label>
+            </subviews>
+            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
+            <constraints>
+                <constraint firstItem="tfN-3g-Eip" firstAttribute="centerY" secondItem="SUI-Ti-MzO" secondAttribute="centerY" id="4iR-2i-2iO"/>
+                <constraint firstItem="SUI-Ti-MzO" firstAttribute="top" secondItem="lOs-av-owS" secondAttribute="bottom" constant="8" id="G7Z-PO-jYn"/>
+                <constraint firstItem="SUI-Ti-MzO" firstAttribute="top" secondItem="bF6-xd-1LF" secondAttribute="top" constant="20" id="Krm-0h-8e9"/>
+                <constraint firstItem="Rev-2X-b5J" firstAttribute="top" secondItem="bF6-xd-1LF" secondAttribute="bottom" constant="12" id="NLa-Co-q9p"/>
+                <constraint firstItem="SUI-Ti-MzO" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="P90-9i-wGM"/>
+                <constraint firstItem="bF6-xd-1LF" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Rtl-2b-xtU"/>
+                <constraint firstItem="tfN-3g-Eip" firstAttribute="centerX" secondItem="SUI-Ti-MzO" secondAttribute="leading" id="XYt-JF-0av"/>
+                <constraint firstItem="bF6-xd-1LF" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="eSt-r7-R85"/>
+                <constraint firstItem="lOs-av-owS" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="raj-wp-VON"/>
+                <constraint firstItem="Rev-2X-b5J" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="uHO-oY-pg3"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="imageWidth" destination="wgg-ol-s5w" id="ghk-aM-7Mc"/>
+                <outlet property="leadingSpace" destination="XYt-JF-0av" id="ugO-sL-Iph"/>
+                <outlet property="progressFillImage" destination="dij-Zh-MfT" id="g8N-Be-ems"/>
+                <outlet property="progressTipsLabel" destination="Rev-2X-b5J" id="NRr-kM-4Fg"/>
+                <outlet property="progressView" destination="SUI-Ti-MzO" id="dbn-Ug-C4y"/>
+            </connections>
+            <point key="canvasLocation" x="287.78625954198475" y="-32.74647887323944"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="progressLoading_bg" width="232" height="52"/>
+        <image name="progress_dot" width="39" height="42"/>
+    </resources>
+</document>

+ 2 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/KSAudioAnimationView.h

@@ -11,6 +11,8 @@ NS_ASSUME_NONNULL_BEGIN
 
 @interface KSAudioAnimationView : UIView
 
+- (void)configWithImageWithUrl:(NSString *)imageUrl;
+
 @property (nonatomic, assign) BOOL isPlay;
 
 + (instancetype)shareInstance;

+ 9 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/KSAudioAnimationView.m

@@ -36,6 +36,15 @@
     stylusImage.center = CGPointMake(stylusImage.center.x - transition.x, stylusImage.center.y - transition.y);
 }
 
+- (void)configWithImageWithUrl:(NSString *)imageUrl {
+    if ([NSString isEmptyString:imageUrl]) {
+        [self.music_image setImage:[UIImage imageNamed:@"pub_music_placeholder"]];
+    }
+    else {
+        [self.music_image sd_setImageWithURL:[NSURL URLWithString:[imageUrl getUrlEndcodeString]]];
+    }
+}
+
 - (void)transformStylusView:(BOOL)isHide {
     if (isHide) {
         self.stylusImage.transform = CGAffineTransformIdentity;

+ 223 - 67
KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/KSMediaMergeView.m

@@ -19,8 +19,10 @@
 #import "KSNewAlertView.h"
 #import "MusicPublistAlert.h"
 #import "KSMediaManager.h"
+#import <RSKImageCropper/RSKImageCropper.h>
+#import "KSVideoCropViewController.h"
 
-@interface KSMediaMergeView ()<kSNewPlayerManagerDelegate,KSVideoPlayerViewDelegate>
+@interface KSMediaMergeView ()<kSNewPlayerManagerDelegate,KSVideoPlayerViewDelegate,RSKImageCropViewControllerDelegate,RSKImageCropViewControllerDataSource>
 
 @property (nonatomic, strong) KSAudioAnimationView *animationView;
 
@@ -99,6 +101,14 @@
 
 @property (nonatomic, assign) BOOL hasModify;
 
+@property (nonatomic, strong) UIImage *videoCoverImage;
+
+@property (nonatomic, assign) BOOL isChooseVideoCover;
+
+@property (nonatomic, strong) NSString *videoCoverUrl; // 视频封面
+
+@property (nonatomic, strong) dispatch_group_t uploadGroup;
+
 @end
 
 @implementation KSMediaMergeView
@@ -192,7 +202,6 @@
             self.videoUrl = fileUrl;
         } faliure:^(NSError * _Nonnull error) {
             dispatch_group_leave(self.requestGroup);
-
         }];
     }
 }
@@ -557,9 +566,8 @@
 
 - (void)showPublishAlert {
     self.publishAlert = [MusicPublistAlert shareInstance];
-    self.publishAlert.musicName.text = [NSString returnNoNullStringWithString:self.songName];
-    [self.publishAlert.musicImage sd_setImageWithURL:[NSURL URLWithString:[self.coverImage getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"pub_music_placeholder"]];
-    self.publishAlert.userName.text = [NSString returnNoNullStringWithString:UserDefault(NicknameKey)];
+    [self.publishAlert configUI:self.isVideoPlay];
+    [self.publishAlert evaluateMusicName:self.songName userName:UserDefault(NicknameKey) musicImage:self.coverImage];
     MJWeakSelf;
     [self.publishAlert chooseAction:^(PUBLISH_ACTION type) {
         [weakSelf publishAction:type];
@@ -571,9 +579,9 @@
     switch (type) {
         case PUBLISH_ACTION_PUBLISH:
         {
-            self.desc = [NSString isEmptyString:self.publishAlert.textView.text] ? @"我发布了一首演奏作品,快来听听吧~" :self.publishAlert.textView.text;
-            if (self.settingImage) { // 上传图片
-                [self updateWithCoverImage:self.settingImage];
+            self.desc = [NSString isEmptyString:self.publishAlert.publishContainView.textView.text] ? @"我发布了一首演奏作品,快来听听吧~" :self.publishAlert.publishContainView.textView.text;
+            if (self.settingImage || self.videoCoverImage) { // 上传图片
+                [self updateWithCoverImage];
             }
             else { // 直接上传
                 [self publishMusic];
@@ -588,61 +596,152 @@
             self.mediaManager.maxPhotoNumber = 1;
             self.mediaManager.baseCtrl = [self findViewController];
 
+            self.mediaManager.needCropImage = YES;
+            MJWeakSelf;
+            [self.mediaManager noAlertCallback:^(NSString * _Nullable videoUrl, NSMutableArray * _Nullable imageArray, NSMutableArray * _Nullable imageAsset) {
+                // 裁剪
+                UIImage *sendImg = [imageArray lastObject];
+                // 跳转到裁剪功能
+                RSKImageCropViewController *imageCropVC = [[RSKImageCropViewController alloc] initWithImage:sendImg cropMode:RSKImageCropModeCustom];
+                imageCropVC.avoidEmptySpaceAroundImage = YES;
+                imageCropVC.rotationEnabled = YES;
+                imageCropVC.delegate = weakSelf;
+                imageCropVC.dataSource = weakSelf;
+                imageCropVC.modalPresentationStyle = UIModalPresentationFullScreen;
+                UIViewController *baseCtrl = [weakSelf findViewController];
+                [baseCtrl.navigationController presentViewController:imageCropVC animated:YES completion:nil];
+            }];
+            [self.mediaManager pushImagePickerController];
+        }
+            break;
+        case PUBLISH_ACTION_VIDEOCOVER: // 视频封面
+        {
+            self.isChooseVideoCover = YES;
+            // 调用相册
+            self.mediaManager = [[KSMediaManager alloc] init];
+            self.mediaManager.mediaType = MEDIATYPE_PHOTO;
+            self.mediaManager.maxPhotoNumber = 1;
+            self.mediaManager.baseCtrl = [self findViewController];
+
             self.mediaManager.needCropImage = NO;
             MJWeakSelf;
             [self.mediaManager noAlertCallback:^(NSString * _Nullable videoUrl, NSMutableArray * _Nullable imageArray, NSMutableArray * _Nullable imageAsset) {
-                [weakSelf refreshViewCoverImg:imageArray];
+                // 裁剪
+                UIImage *sendImg = [imageArray lastObject];
+                // 跳转到裁剪功能
+                RSKImageCropViewController *imageCropVC = [[RSKImageCropViewController alloc] initWithImage:sendImg cropMode:RSKImageCropModeCustom];
+                imageCropVC.avoidEmptySpaceAroundImage = YES;
+                imageCropVC.rotationEnabled = YES;
+                imageCropVC.delegate = weakSelf;
+                imageCropVC.dataSource = weakSelf;
+                imageCropVC.modalPresentationStyle = UIModalPresentationFullScreen;
+                UIViewController *baseCtrl = [weakSelf findViewController];
+                [baseCtrl.navigationController presentViewController:imageCropVC animated:YES completion:nil];
             }];
             [self.mediaManager pushImagePickerController];
         }
             break;
+        case PUBLISH_ACTION_VIDEOCROP:
+        {
+            KSVideoCropViewController *ctrl = [[KSVideoCropViewController alloc] init];
+            [ctrl configWithVideoPath:self.videoUrl];
+            UIViewController *baseCtrl = [self findViewController];
+            MJWeakSelf;
+            [ctrl chooseCropImageCallback:^(UIImage * _Nonnull cropImage) {
+                [weakSelf displayCoverImage:cropImage];
+            }];
+            [baseCtrl.navigationController presentViewController:ctrl animated:YES completion:nil];
+        }
+            break;
         default:
             break;
     }
 }
 
-- (void)updateWithCoverImage:(UIImage *)image {
-    NSData *imgData = [UIImage turnsImaegDataByImage:image];
+- (void)displayCoverImage:(UIImage *)image {
+    self.videoCoverImage = image;
+    [self.publishAlert.coverView.coverImage setImage:self.videoCoverImage];
+}
+
+- (void)updateWithCoverImage {
+    
+    if (self.settingImage) {
+        [self uploadMusicCover];
+    }
+    if (self.videoCoverImage) {
+        [self uploadVideoCover];
+    }
+    
+    dispatch_group_notify(self.uploadGroup, dispatch_get_main_queue(), ^{
+        [self publishMusic];
+    });
+}
+
+- (void)uploadMusicCover {
+    dispatch_group_enter(self.uploadGroup);
+
+    NSData *imgData = [UIImage turnsImaegDataByImage:self.settingImage];
     NSString *fileName = @"musicCoverImg";
-    [UPLOAD_MANAGER configBucketName:@"daya"];
+    [[KSUploadManager shareInstance] configBucketName:@"klx"];
     [[KSUploadManager shareInstance] uploadImage:imgData fileName:fileName successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
         NSString *avatarUrl = [fileUrlArray lastObject];
         self.coverImage = avatarUrl;
-        [self publishMusic];
+        dispatch_group_leave(self.uploadGroup);
+    } faliure:^(NSError * _Nullable error, NSString *descMessaeg) {
+        if ([NSString isEmptyString:descMessaeg]) {
+            [LOADING_MANAGER MBShowAUTOHidingInWindow:descMessaeg];
+        }
+        dispatch_group_leave(self.uploadGroup);
+    }];
+}
+
+- (void)uploadVideoCover {
+    dispatch_group_enter(self.uploadGroup);
+    NSData *imgData = [UIImage turnsImaegDataByImage:self.videoCoverImage];
+    NSString *fileName = @"musicCoverImg";
+    [[KSUploadManager shareInstance] configBucketName:@"klx"];
+    [[KSUploadManager shareInstance] uploadImage:imgData fileName:fileName successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
+        NSString *avatarUrl = [fileUrlArray lastObject];
+        self.videoCoverUrl = avatarUrl;
+        dispatch_group_leave(self.uploadGroup);
     } faliure:^(NSError * _Nullable error, NSString *descMessaeg) {
         if ([NSString isEmptyString:descMessaeg]) {
             [LOADING_MANAGER MBShowAUTOHidingInWindow:descMessaeg];
         }
+        dispatch_group_leave(self.uploadGroup);
+
     }];
 }
 
 - (void)refreshViewCoverImg:(NSMutableArray *)imageArray {
     UIImage *img = [imageArray lastObject];
     self.settingImage = img;
-    [self.publishAlert.musicImage setImage:self.settingImage];
-    
+    [self.publishAlert.publishContainView.musicImage setImage:self.settingImage];
 }
 
 
 - (void)publishMusic {
     if (self.isVideoPlay) {
-        [LOADING_MANAGER showCustomLoading:@"视频合成中..."];
+        [LOADING_MANAGER showProgressLoading:@"视频合成中" progress:33];
         [KSMediaEditor mixVideoWithRecordAudio:self.recordUrl recordVolume:self.recordPlayer.volume bgAudio:self.bgAudioUrl bgAudioVolume:self.bgPlayer.volume offsetTime:self.offsetTime videoUrlStr:self.videoUrl completion:^(NSString * _Nonnull outPath, BOOL isSuccess, NSString * _Nonnull desc) {
             // 保存文件到指定文件夹
             if (isSuccess) {
                 self.filePath = outPath;
                 MJWeakSelf;
-                [self saveVideoToAsset:outPath isFormal:YES callback:^(NSString *videoUrl) {
-                    [weakSelf saveMusic:YES isFormal:YES fileUrl:videoUrl];
+                [self sendVideoActionWithUrl:outPath isFormal:YES success:^(NSString * _Nonnull uploadVideoUrl) {
+                    [weakSelf saveMusic:YES isFormal:YES fileUrl:uploadVideoUrl progress:66];
+
+                } failure:^(NSString * _Nonnull desc) {
+                    
                 }];
             }
             else {
-                [LOADING_MANAGER removeCustomLoading];
+                [LOADING_MANAGER removeProgressLoading];
             }
         }];
     }
     else {
-        [LOADING_MANAGER showCustomLoading:@"音频合成中..."];
+        [LOADING_MANAGER showProgressLoading:@"音频合成中..." progress:33];
         NSInteger realOffsetTime = self.offsetTime;
         [KSMediaEditor mixRecordAudio:self.recordUrl recordVolume:self.recordPlayer.volume bgAudio:self.bgAudioUrl bgAudioVolume:self.bgPlayer.volume offsetTime:realOffsetTime completion:^(NSString * _Nonnull outPath, BOOL isSuccess, NSString * _Nonnull desc) {
             // 保存文件到指定文件夹
@@ -650,13 +749,13 @@
                 self.filePath = outPath;
                 MJWeakSelf;
                 [self sendAudioWithPath:outPath isFormal:YES success:^(NSString *audioUrl) {
-                    [weakSelf saveMusic:NO isFormal:YES fileUrl:audioUrl];
+                    [weakSelf saveMusic:NO isFormal:YES fileUrl:audioUrl progress:66];
                 } failure:^(NSString *desc) {
                     [LOADING_MANAGER MBShowAUTOHidingInWindow:@"文件上传失败"];
                 }];
             }
             else {
-                [LOADING_MANAGER removeCustomLoading];
+                [LOADING_MANAGER removeProgressLoading];
             }
         }];
     }
@@ -668,34 +767,36 @@
     if (self.isVideoPlay) {
         if (self.remoteVideoUrl) {
             // 保存草稿
-            [self saveMusic:YES isFormal:NO fileUrl:self.remoteVideoUrl needBack:needBack];
+            [self saveMusic:YES isFormal:NO fileUrl:self.remoteVideoUrl needBack:needBack progress:33];
         }
         else {
-            [LOADING_MANAGER showCustomLoading:@"正在上传草稿"];
-            [KSMediaEditor mixRecordVideoWithAudio:self.recordUrl recordVolume:1 videoUrlStr:self.videoUrl completion:^(NSString * _Nonnull outPath, BOOL isSuccess, NSString * _Nonnull desc) {
+            // 合成
+            [LOADING_MANAGER showProgressLoading:@"加载中..." progress:33];
+            MJWeakSelf;
+            [KSMediaEditor mixRecordVideoWithAudio:self.recordUrl recordVolume:100 videoUrlStr:self.videoUrl completion:^(NSString * _Nonnull outPath, BOOL isSuccess, NSString * _Nonnull desc) {
                 if (isSuccess) {
-                    MJWeakSelf;
-                    [self saveVideoToAsset:outPath isFormal:NO callback:^(NSString *videoUrl) {
+                    [self sendVideoActionWithUrl:outPath isFormal:NO success:^(NSString * _Nonnull uploadVideoUrl) {
                         // 保存草稿
-                        [weakSelf saveMusic:YES isFormal:NO fileUrl:videoUrl needBack:needBack];
+                        [weakSelf saveMusic:YES isFormal:NO fileUrl:uploadVideoUrl needBack:needBack progress:66];
+                    } failure:^(NSString * _Nonnull desc) {
+                        [LOADING_MANAGER MBShowAUTOHidingInWindow:@"上传失败"];
                     }];
                 }
                 else {
-                    [LOADING_MANAGER removeCustomLoading];
-
+                    [LOADING_MANAGER MBShowAUTOHidingInWindow:@"上传失败"];
                 }
             }];
         }
     }
     else {
         if (self.remoteRecrodUrl) {
-            [self saveMusic:NO isFormal:NO fileUrl:self.remoteRecrodUrl needBack:needBack];
+            [self saveMusic:NO isFormal:NO fileUrl:self.remoteRecrodUrl needBack:needBack progress:33];
         }
         else {
             MJWeakSelf;
             [self sendAudioWithURLPath:self.recordUrl isFormal:NO success:^(NSString *audioUrl) {
                 
-                [weakSelf saveMusic:NO isFormal:NO fileUrl:audioUrl needBack:needBack];
+                [weakSelf saveMusic:NO isFormal:NO fileUrl:audioUrl needBack:needBack progress:33];
             } failure:^(NSString *desc) {
                 [LOADING_MANAGER MBShowAUTOHidingInWindow:@"文件上传失败"];
             }];
@@ -754,7 +855,7 @@
         self.playControlView.playScheduleTime = (NSInteger)(playTime / 1000);
     }
     else {
-        NSLog(@"--- ---- bgPlayer   ----- %f", playTime);
+//        NSLog(@"--- ---- bgPlayer   ----- %f", playTime);
     }
 }
 
@@ -855,29 +956,28 @@
     }];
 }
 
-- (void)saveMusic:(BOOL)isVideo isFormal:(BOOL)isFormal fileUrl:(NSString *)fileUrl  {
+- (void)saveMusic:(BOOL)isVideo isFormal:(BOOL)isFormal fileUrl:(NSString *)fileUrl progress:(NSInteger)progress  {
     
-    [self saveMusic:isVideo isFormal:isFormal fileUrl:fileUrl needBack:NO];
+    [self saveMusic:isVideo isFormal:isFormal fileUrl:fileUrl needBack:NO progress:progress];
 }
 
-- (void)saveMusic:(BOOL)isVideo isFormal:(BOOL)isFormal fileUrl:(NSString *)fileUrl needBack:(BOOL)needBack {
+- (void)saveMusic:(BOOL)isVideo isFormal:(BOOL)isFormal fileUrl:(NSString *)fileUrl needBack:(BOOL)needBack progress:(NSInteger)progress {
     NSString *type = isFormal ? @"FORMAL" : @"DRAFT";
     NSMutableDictionary *parm = [NSMutableDictionary dictionary];
     [parm setValue:@(self.offsetTime) forKey:@"offset"];
     [parm setValue:@(self.originalVolume) forKey:@"originalVolume"];
     [parm setValue:@(self.accompanyVolume) forKey:@"accompanyVolume"];
     self.jsonConfig = [parm mj_JSONString];
-    [LOADING_MANAGER showCustomLoading:@"加载中..."];
-    [KSNetworkingManager saveMusicMessage:KS_POST jsonConfig:self.jsonConfig img:self.coverImage videoUrl:fileUrl accompanyUrl:self.remoteBgAudioUrl desc:self.desc type:type musicPracticeRecordId:self.recordId success:^(NSDictionary * _Nonnull dic) {
-        [LOADING_MANAGER removeCustomLoading];
+    [LOADING_MANAGER showProgressLoading:@"加载中..." progress:progress];
+    [KSNetworkingManager saveMusicMessage:KS_POST jsonConfig:self.jsonConfig img:self.coverImage videoUrl:fileUrl accompanyUrl:self.remoteBgAudioUrl desc:self.desc type:type musicPracticeRecordId:self.recordId videoImg:self.videoCoverUrl success:^(NSDictionary * _Nonnull dic) {
         if ([dic ks_integerValueForKey:@"code"] == 200) {
             if (isFormal) {
-                [LOADING_MANAGER KSShowMsg:@"发布成功" promptCompletion:^{
+                [LOADING_MANAGER KSShowProgressMsg:@"发布成功" promptCompletion:^{
                     [self removeView];
                 }];
             }
             else {
-                [LOADING_MANAGER KSShowMsg:@"保存成功" promptCompletion:^{
+                [LOADING_MANAGER KSShowProgressMsg:@"保存成功" promptCompletion:^{
                     self.hasModify = NO;
                     if (needBack) {
                         [self removeViewTips:NO];
@@ -886,10 +986,11 @@
             }
         }
         else {
+            [LOADING_MANAGER removeProgressLoading];
             [LOADING_MANAGER MBShowAUTOHidingInWindow:MESSAGEKEY];
         }
     } faliure:^(NSError * _Nonnull error) {
-        [LOADING_MANAGER removeCustomLoading];
+        [LOADING_MANAGER removeProgressLoading];
     }];
 }
 
@@ -905,7 +1006,7 @@
                 NSLog(@"导出后的视频:%@",[NSString stringWithFormat:@"%.2fM",(CGFloat)outputData.length/(1024*1024)]);
                 // 上传
                 dispatch_main_async_safe(^{
-                    [self sendVideoActionWith:outputPath isFormal:isFormal success:success failure:faliure];
+                    [self sendVideoActionWithUrl:outputPath isFormal:isFormal success:success failure:faliure];
                 });
                 
             } failure:^(NSString *errorMessage, NSError *error) {
@@ -925,23 +1026,16 @@
     }
 }
 
-
-- (void)sendVideoActionWith:(NSString *)fileUrl isFormal:(BOOL)isFormal success:(void (^)(NSString * _Nonnull))success failure:(void (^)(NSString * _Nonnull))faliure {
+- (void)sendVideoActionWithUrlPath:(NSURL *)fileUrl isFormal:(BOOL)isFormal success:(void (^)(NSString * _Nonnull uploadVideoUrl))success failure:(void (^)(NSString * _Nonnull desc))faliure {
     NSString *tips = isFormal ? @"正在上传作品" : @"正在上传草稿";
-    [LOADING_MANAGER showCustomLoading:tips];
-    NSData *fileData = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:fileUrl]];
+    [LOADING_MANAGER showProgressLoading:tips progress:66];
+    NSData *fileData = [NSData dataWithContentsOfURL:fileUrl];
     NSString *suffix = [NSString stringWithFormat:@".%@",[fileUrl pathExtension]];
-    [UPLOAD_MANAGER configBucketName:@"daya"];
+    [[KSUploadManager shareInstance] configBucketName:@"klx"];
     [[KSUploadManager shareInstance] videoUpload:fileData fileName:@"video" fileSuffix:suffix progress:^(int64_t bytesWritten, int64_t totalBytes) {
-        // 显示进度
-        int progress = (int)(bytesWritten / totalBytes * 100);
-        __block NSString *tipsMessage = [NSString stringWithFormat:@"%@\n%d%%",tips,progress];
-        dispatch_main_async_safe(^{
-            [LOADING_MANAGER.loadingView setDisplayText:tipsMessage];
-        });
+
     } successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
         dispatch_main_async_safe(^{
-            [LOADING_MANAGER removeCustomLoading];
             NSString *fileUrl = [fileUrlArray lastObject];
             success(fileUrl);
         });
@@ -949,33 +1043,31 @@
         
     } faliure:^(NSError * _Nullable error, NSString * _Nullable descMessaeg) {
         dispatch_main_async_safe(^{
-            [LOADING_MANAGER removeCustomLoading];
+            [LOADING_MANAGER removeProgressLoading];
             faliure(descMessaeg);
         });
         
     }];
 }
 
+- (void)sendVideoActionWithUrl:(NSString *)fileUrl isFormal:(BOOL)isFormal success:(void (^)(NSString * _Nonnull uploadVideoUrl))success failure:(void (^)(NSString * _Nonnull desc))faliure {
+    [self sendAudioWithURLPath:[NSURL fileURLWithPath:fileUrl] isFormal:isFormal success:success failure:faliure];
+}
+
 - (void)sendAudioWithURLPath:(NSURL *)fileUrl isFormal:(BOOL)isFormal success:(void(^)(NSString *audioUrl))success failure:(void(^)(NSString *desc))faliure {
     NSString *tips = isFormal ? @"正在上传作品" : @"正在上传草稿";
 
-    [LOADING_MANAGER showCustomLoading:tips];
+    [LOADING_MANAGER showProgressLoading:tips progress:66];
     NSData *fileData = [NSData dataWithContentsOfURL:fileUrl];
     NSString *suffix = [NSString stringWithFormat:@".%@",[fileUrl pathExtension]];
-    [UPLOAD_MANAGER configBucketName:@"daya"];
+    [[KSUploadManager shareInstance] configBucketName:@"klx"];
     [UPLOAD_MANAGER uploadFile:fileData fileName:@"evaluateAudio" fileSuffix:suffix progress:^(int64_t bytesWritten, int64_t totalBytes) {
-        // 显示进度
-        int progress = (int)(bytesWritten / totalBytes * 100);
-        __block NSString *tipsMessage = [NSString stringWithFormat:@"%@\n%d%%",tips,progress];
-        dispatch_main_async_safe(^{
-            [LOADING_MANAGER.loadingView setDisplayText:tipsMessage];
-        });
+
     } successCallback:^(NSMutableArray * _Nonnull fileUrlArray) {
-        [LOADING_MANAGER removeCustomLoading];
         NSString *fileUrl = [fileUrlArray lastObject];
         success(fileUrl);
     } faliure:^(NSError * _Nullable error, NSString * _Nullable descMessaeg) {
-        [LOADING_MANAGER removeCustomLoading];
+        [LOADING_MANAGER removeProgressLoading];
         faliure(descMessaeg);
     }];
     
@@ -1057,7 +1149,12 @@
     }
     return _requestGroup;
 }
-
+- (dispatch_group_t)uploadGroup {
+    if (!_uploadGroup) {
+        _uploadGroup = dispatch_group_create();
+    }
+    return _uploadGroup;
+}
 - (KSNewAlertView *)alertView {
     if (!_alertView) {
         _alertView = [KSNewAlertView shareInstance];
@@ -1076,6 +1173,65 @@
     return nil;
 }
 
+#pragma mark --- RSKImageCropViewControllerDelegate
+
+- (CGRect)imageCropViewControllerCustomMaskRect:(RSKImageCropViewController *)controller {
+    CGFloat height = KLandscapeHeight - 80;
+    
+    CGFloat width = height;
+    if (self.isChooseVideoCover) {
+        width = height / 9 * 16;
+
+    }
+    return CGRectMake((KLandscapeWidth - width) / 2.0f, (KLandscapeHeight - height) / 2.0f, width, height);
+}
+
+- (UIBezierPath *)imageCropViewControllerCustomMaskPath:(RSKImageCropViewController *)controller {
+    //返回裁剪框的位置
+    CGFloat height = KLandscapeHeight - 80;
+    CGFloat width = height;
+    if (self.isChooseVideoCover) {
+        width = height / 9 * 16;
+    }
+    UIBezierPath *path=[UIBezierPath bezierPathWithRoundedRect:CGRectMake((KLandscapeWidth - width) / 2.0f, (KLandscapeHeight - height) / 2.0f, width, height) cornerRadius:0];
+    return path;
+}
+/**
+返回一个图片可以移动的矩形区域
+仅在RSKImageCropModeCustom下有效
+如果你想支持图片旋转,则必须实现该方法
+ */
+- (CGRect)imageCropViewControllerCustomMovementRect:(RSKImageCropViewController *)controller
+{
+    return controller.maskRect;
+}
+
+/**
+ 通知 delegate 取消裁剪图像。
+ */
+- (void)imageCropViewControllerDidCancelCrop:(RSKImageCropViewController *)controller {
+    if (self.isChooseVideoCover) {
+        self.isChooseVideoCover = NO;
+    }
+    [controller dismissViewControllerAnimated:YES completion:nil];
+}
+
+/**
+ 通知 delegate 原始图像已经被裁剪。此外,还提供了一个裁剪矩形和用于生成图像的旋转角度。
+ */
+- (void)imageCropViewController:(RSKImageCropViewController *)controller didCropImage:(UIImage *)croppedImage usingCropRect:(CGRect)cropRect rotationAngle:(CGFloat)rotationAngle {
+//    croppedImage
+    if (self.isChooseVideoCover) {
+        self.isChooseVideoCover = NO;
+        [self displayCoverImage:croppedImage];
+    }
+    else {
+        self.settingImage = croppedImage;
+        [self.publishAlert.publishContainView.musicImage setImage:self.settingImage];
+    }
+    
+    [controller dismissViewControllerAnimated:YES completion:nil];
+}
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.

+ 4 - 4
KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/KSMergeAudioControlView.xib

@@ -233,7 +233,7 @@
                             </connections>
                         </button>
                         <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nyI-H7-gwi">
-                            <rect key="frame" x="13" y="54" width="34" height="34"/>
+                            <rect key="frame" x="250" y="54" width="34" height="34"/>
                             <subviews>
                                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="slider_bubble" translatesAutoresizingMaskIntoConstraints="NO" id="ahK-NK-SMi">
                                     <rect key="frame" x="0.0" y="0.0" width="34" height="34"/>
@@ -256,7 +256,7 @@
                             </constraints>
                         </view>
                         <view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Z4q-fo-efi">
-                            <rect key="frame" x="13" y="137" width="34" height="34"/>
+                            <rect key="frame" x="250" y="137" width="34" height="34"/>
                             <subviews>
                                 <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="slider_bubble" translatesAutoresizingMaskIntoConstraints="NO" id="qaQ-ih-J2u">
                                     <rect key="frame" x="0.0" y="0.0" width="34" height="34"/>
@@ -316,7 +316,7 @@
                         <constraint firstItem="if2-R5-Tul" firstAttribute="leading" secondItem="dNG-od-Opv" secondAttribute="leading" constant="26" id="Tbj-uW-5vm"/>
                         <constraint firstItem="if2-R5-Tul" firstAttribute="top" secondItem="pQK-tY-S1I" secondAttribute="bottom" constant="20" id="U6A-D9-FMf"/>
                         <constraint firstItem="MX8-jr-euo" firstAttribute="centerY" secondItem="gDH-uC-2DO" secondAttribute="centerY" id="W2M-EL-mO7"/>
-                        <constraint firstItem="Z4q-fo-efi" firstAttribute="centerX" secondItem="dNG-od-Opv" secondAttribute="leading" constant="30" id="WVs-oc-QrV"/>
+                        <constraint firstItem="Z4q-fo-efi" firstAttribute="centerX" secondItem="dNG-od-Opv" secondAttribute="leading" constant="267" id="WVs-oc-QrV"/>
                         <constraint firstItem="slK-h7-P25" firstAttribute="top" secondItem="XPO-nW-Uox" secondAttribute="bottom" constant="12" id="ZPv-OR-vc2"/>
                         <constraint firstItem="f5Q-wh-6l8" firstAttribute="centerX" secondItem="Jqd-bC-HWT" secondAttribute="centerX" id="aUL-2e-p91"/>
                         <constraint firstItem="ZEM-tW-WX9" firstAttribute="top" secondItem="dNG-od-Opv" secondAttribute="top" constant="14" id="ddY-o0-jeB"/>
@@ -332,7 +332,7 @@
                         <constraint firstItem="gDH-uC-2DO" firstAttribute="leading" secondItem="dNG-od-Opv" secondAttribute="leading" constant="8" id="hut-3H-gU3"/>
                         <constraint firstAttribute="bottom" secondItem="VTj-cX-p66" secondAttribute="bottom" constant="67" id="iPG-s9-hwk"/>
                         <constraint firstItem="imR-Qo-Jpf" firstAttribute="leading" secondItem="slK-h7-P25" secondAttribute="trailing" constant="6" id="iTt-Wy-aYO"/>
-                        <constraint firstItem="nyI-H7-gwi" firstAttribute="centerX" secondItem="dNG-od-Opv" secondAttribute="leading" constant="30" id="jdI-be-CFN"/>
+                        <constraint firstItem="nyI-H7-gwi" firstAttribute="centerX" secondItem="dNG-od-Opv" secondAttribute="leading" constant="267" id="jdI-be-CFN"/>
                         <constraint firstItem="DzT-go-dxS" firstAttribute="top" secondItem="pQK-tY-S1I" secondAttribute="top" constant="-5" id="kMt-a5-3io"/>
                         <constraint firstItem="Q7z-0G-roa" firstAttribute="top" secondItem="VTj-cX-p66" secondAttribute="bottom" constant="10" id="kNw-jw-Ek9"/>
                         <constraint firstItem="pQK-tY-S1I" firstAttribute="top" secondItem="oyf-C4-Pe3" secondAttribute="bottom" constant="16" id="lye-Zg-T75"/>

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/KSPlayerSliderView.m

@@ -52,7 +52,7 @@
         UIView *sliderImg = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 12, 12)];
         sliderImg.layer.cornerRadius = 6.0f;
         sliderImg.layer.masksToBounds = YES;
-        sliderImg.backgroundColor = HexRGB(0x269EFE);
+        sliderImg.backgroundColor = HexRGB(0x2DC7AA);
         UIImage *image = [UIView convertViewToImage:sliderImg];
         [self.progressSlider setThumbImage:image forState:UIControlStateNormal];
         [self.progressSlider setThumbImage:image forState:UIControlStateHighlighted];

+ 0 - 272
KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/MusicPublistAlert.xib

@@ -1,272 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
-    <device id="retina6_12" orientation="portrait" appearance="light"/>
-    <dependencies>
-        <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
-        <capability name="System colors in document resources" minToolsVersion="11.0"/>
-        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MusicPublistAlert">
-            <rect key="frame" x="0.0" y="0.0" width="687" height="520"/>
-            <autoresizingMask key="autoresizingMask"/>
-            <subviews>
-                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="crp-Dg-bEh">
-                    <rect key="frame" x="185.66666666666663" y="104.66666666666669" width="316" height="311"/>
-                    <subviews>
-                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="作品详情" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="te4-O1-RAs">
-                            <rect key="frame" x="125.33333333333334" y="15" width="65.333333333333343" height="22"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="22" id="9P9-gf-TQs"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
-                            <color key="textColor" red="0.074509803921568626" green="0.078431372549019607" blue="0.082352941176470587" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <nil key="highlightedColor"/>
-                        </label>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="CTY-Fx-tzH">
-                            <rect key="frame" x="12" y="51.999999999999986" width="292" height="87.000000000000014"/>
-                            <subviews>
-                                <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="WQ8-cQ-EDG">
-                                    <rect key="frame" x="12" y="0.0" width="268" height="87"/>
-                                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                                    <color key="textColor" red="0.2666666667" green="0.2666666667" blue="0.2666666667" alpha="1" colorSpace="calibratedRGB"/>
-                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                                    <textInputTraits key="textInputTraits" autocapitalizationType="sentences" enablesReturnKeyAutomatically="YES"/>
-                                </textView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我发布了一首演奏作品,快来听听吧~" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9AA-e2-K2q">
-                                    <rect key="frame" x="12" y="10" width="243" height="17"/>
-                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                                    <color key="textColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0/150" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="em6-7z-Xgu">
-                                    <rect key="frame" x="248" y="58" width="32" height="20"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="20" id="34t-Kc-j7t"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="12"/>
-                                    <color key="textColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                            </subviews>
-                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                            <constraints>
-                                <constraint firstAttribute="trailing" secondItem="em6-7z-Xgu" secondAttribute="trailing" constant="12" id="F5G-2F-xMS"/>
-                                <constraint firstAttribute="bottom" secondItem="em6-7z-Xgu" secondAttribute="bottom" constant="9" id="IiE-1G-erd"/>
-                                <constraint firstItem="WQ8-cQ-EDG" firstAttribute="leading" secondItem="CTY-Fx-tzH" secondAttribute="leading" constant="12" id="JOz-Zs-M9D"/>
-                                <constraint firstAttribute="trailing" secondItem="WQ8-cQ-EDG" secondAttribute="trailing" constant="12" id="Wfg-qP-9ez"/>
-                                <constraint firstItem="9AA-e2-K2q" firstAttribute="leading" secondItem="CTY-Fx-tzH" secondAttribute="leading" constant="12" id="XBD-OF-F8e"/>
-                                <constraint firstItem="9AA-e2-K2q" firstAttribute="top" secondItem="CTY-Fx-tzH" secondAttribute="top" constant="10" id="bSD-PX-0Jh"/>
-                                <constraint firstItem="WQ8-cQ-EDG" firstAttribute="top" secondItem="CTY-Fx-tzH" secondAttribute="top" id="lj6-bB-3sT"/>
-                                <constraint firstAttribute="height" constant="87" id="mHx-kV-2g8"/>
-                                <constraint firstAttribute="bottom" secondItem="WQ8-cQ-EDG" secondAttribute="bottom" id="mZ3-oV-sMo"/>
-                            </constraints>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="10"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                        </view>
-                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="l5g-yG-AJ9">
-                            <rect key="frame" x="12" y="151" width="292" height="86"/>
-                            <subviews>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="music_coverBg" translatesAutoresizingMaskIntoConstraints="NO" id="EP2-DU-ddy">
-                                    <rect key="frame" x="19" y="12.333333333333343" width="61" height="61"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="61" id="DTT-42-ivC"/>
-                                        <constraint firstAttribute="width" constant="61" id="hgd-Hf-dTV"/>
-                                    </constraints>
-                                </imageView>
-                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="pub_music_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="VVv-Nb-ldQ">
-                                    <rect key="frame" x="12" y="12.000000000000028" width="62" height="62"/>
-                                    <constraints>
-                                        <constraint firstAttribute="width" constant="62" id="LVE-t7-SCr"/>
-                                        <constraint firstAttribute="height" constant="62" id="pjr-Ke-g6S"/>
-                                    </constraints>
-                                    <userDefinedRuntimeAttributes>
-                                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                            <real key="value" value="8"/>
-                                        </userDefinedRuntimeAttribute>
-                                    </userDefinedRuntimeAttributes>
-                                </imageView>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ETV-b6-Fe7">
-                                    <rect key="frame" x="90.000000000000028" y="20.000000000000028" width="189.99999999999997" height="22"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="22" id="77r-wV-D6B"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
-                                    <color key="textColor" red="0.074509803920000006" green="0.078431372550000003" blue="0.08235294118" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="9Ss-uK-g79">
-                                    <rect key="frame" x="90.000000000000028" y="46.000000000000028" width="189.99999999999997" height="20"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="20" id="eD2-NY-Z0M"/>
-                                    </constraints>
-                                    <fontDescription key="fontDescription" type="system" pointSize="14"/>
-                                    <color key="textColor" red="0.46666666666666667" green="0.46666666666666667" blue="0.46666666666666667" alpha="1" colorSpace="calibratedRGB"/>
-                                    <nil key="highlightedColor"/>
-                                </label>
-                                <imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="unChoose_status" translatesAutoresizingMaskIntoConstraints="NO" id="eTy-AP-Nrh">
-                                    <rect key="frame" x="0.0" y="34.000000000000028" width="0.0" height="18"/>
-                                    <constraints>
-                                        <constraint firstAttribute="height" constant="18" id="KB9-Tz-L8j"/>
-                                        <constraint firstAttribute="width" id="bSW-D2-mdn"/>
-                                    </constraints>
-                                </imageView>
-                                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="34Q-Ap-BhT">
-                                    <rect key="frame" x="12" y="54.000000000000028" width="62" height="20"/>
-                                    <subviews>
-                                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="选封面" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p3g-Ea-XCb">
-                                            <rect key="frame" x="11" y="0.0" width="40" height="18"/>
-                                            <constraints>
-                                                <constraint firstAttribute="height" constant="18" id="c6d-6u-Az0"/>
-                                            </constraints>
-                                            <fontDescription key="fontDescription" type="system" pointSize="13"/>
-                                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                                            <nil key="highlightedColor"/>
-                                        </label>
-                                    </subviews>
-                                    <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.37" colorSpace="custom" customColorSpace="calibratedRGB"/>
-                                    <constraints>
-                                        <constraint firstItem="p3g-Ea-XCb" firstAttribute="centerX" secondItem="34Q-Ap-BhT" secondAttribute="centerX" id="GHb-76-r1W"/>
-                                        <constraint firstAttribute="height" constant="20" id="Uih-s7-Z9a"/>
-                                        <constraint firstItem="p3g-Ea-XCb" firstAttribute="top" secondItem="34Q-Ap-BhT" secondAttribute="top" id="VSx-cs-Kk3"/>
-                                        <constraint firstAttribute="width" constant="62" id="vrS-NL-gdO"/>
-                                    </constraints>
-                                </view>
-                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Vxt-nB-ivY">
-                                    <rect key="frame" x="12" y="12.000000000000028" width="62" height="62"/>
-                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                                    <connections>
-                                        <action selector="chooseCover:" destination="iN0-l3-epB" eventType="touchUpInside" id="w2o-dJ-iQE"/>
-                                    </connections>
-                                </button>
-                            </subviews>
-                            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-                            <constraints>
-                                <constraint firstItem="ETV-b6-Fe7" firstAttribute="top" secondItem="l5g-yG-AJ9" secondAttribute="top" constant="20" id="4Us-jY-xaa"/>
-                                <constraint firstItem="Vxt-nB-ivY" firstAttribute="bottom" secondItem="VVv-Nb-ldQ" secondAttribute="bottom" id="6An-Xx-CF5"/>
-                                <constraint firstItem="EP2-DU-ddy" firstAttribute="centerY" secondItem="l5g-yG-AJ9" secondAttribute="centerY" id="9gq-xr-2wm"/>
-                                <constraint firstAttribute="trailing" secondItem="ETV-b6-Fe7" secondAttribute="trailing" constant="12" id="E4Y-l1-IHm"/>
-                                <constraint firstAttribute="trailing" secondItem="9Ss-uK-g79" secondAttribute="trailing" constant="12" id="J9w-hP-R7d"/>
-                                <constraint firstItem="VVv-Nb-ldQ" firstAttribute="leading" secondItem="eTy-AP-Nrh" secondAttribute="trailing" constant="12" id="JjX-9P-cVY"/>
-                                <constraint firstItem="9Ss-uK-g79" firstAttribute="top" secondItem="ETV-b6-Fe7" secondAttribute="bottom" constant="4" id="KIe-Xd-GOo"/>
-                                <constraint firstItem="Vxt-nB-ivY" firstAttribute="trailing" secondItem="VVv-Nb-ldQ" secondAttribute="trailing" id="LAw-gk-MSD"/>
-                                <constraint firstItem="Vxt-nB-ivY" firstAttribute="leading" secondItem="VVv-Nb-ldQ" secondAttribute="leading" id="MYP-CH-MAK"/>
-                                <constraint firstItem="eTy-AP-Nrh" firstAttribute="leading" secondItem="l5g-yG-AJ9" secondAttribute="leading" id="NbV-dJ-UHV"/>
-                                <constraint firstItem="34Q-Ap-BhT" firstAttribute="trailing" secondItem="VVv-Nb-ldQ" secondAttribute="trailing" id="QWA-Ld-U5L"/>
-                                <constraint firstItem="VVv-Nb-ldQ" firstAttribute="trailing" secondItem="EP2-DU-ddy" secondAttribute="trailing" constant="-6" id="Ube-4B-zgW"/>
-                                <constraint firstItem="ETV-b6-Fe7" firstAttribute="leading" secondItem="EP2-DU-ddy" secondAttribute="trailing" constant="10" id="Vzb-js-zep"/>
-                                <constraint firstItem="eTy-AP-Nrh" firstAttribute="centerY" secondItem="l5g-yG-AJ9" secondAttribute="centerY" id="dpC-l5-Vmz"/>
-                                <constraint firstItem="34Q-Ap-BhT" firstAttribute="leading" secondItem="VVv-Nb-ldQ" secondAttribute="leading" id="g9W-eP-Dap"/>
-                                <constraint firstItem="9Ss-uK-g79" firstAttribute="leading" secondItem="ETV-b6-Fe7" secondAttribute="leading" id="i9d-wq-Qav"/>
-                                <constraint firstAttribute="height" constant="86" id="oDT-wq-TI3"/>
-                                <constraint firstItem="34Q-Ap-BhT" firstAttribute="bottom" secondItem="VVv-Nb-ldQ" secondAttribute="bottom" id="owr-L6-tci"/>
-                                <constraint firstItem="VVv-Nb-ldQ" firstAttribute="centerY" secondItem="l5g-yG-AJ9" secondAttribute="centerY" id="wAx-Fn-njL"/>
-                                <constraint firstItem="Vxt-nB-ivY" firstAttribute="top" secondItem="VVv-Nb-ldQ" secondAttribute="top" id="xuK-Jq-o5D"/>
-                            </constraints>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="10"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                        </view>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mxv-fX-f3j">
-                            <rect key="frame" x="48" y="255" width="220" height="38"/>
-                            <color key="backgroundColor" red="0.1764705882" green="0.78039215689999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="220" id="5fw-Lh-5Er"/>
-                                <constraint firstAttribute="height" constant="38" id="qZJ-YL-FtZ"/>
-                            </constraints>
-                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
-                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                            <state key="normal" title="发布作品"/>
-                            <userDefinedRuntimeAttributes>
-                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                                    <real key="value" value="19"/>
-                                </userDefinedRuntimeAttribute>
-                            </userDefinedRuntimeAttributes>
-                            <connections>
-                                <action selector="sureAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="AMG-ZX-bXR"/>
-                            </connections>
-                        </button>
-                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cancle_button" translatesAutoresizingMaskIntoConstraints="NO" id="uSL-RT-oX5">
-                            <rect key="frame" x="287" y="11" width="19" height="19"/>
-                            <constraints>
-                                <constraint firstAttribute="width" constant="19" id="LRY-32-rBI"/>
-                                <constraint firstAttribute="height" constant="19" id="dWq-Go-3Vb"/>
-                            </constraints>
-                        </imageView>
-                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8mM-Qw-PGH">
-                            <rect key="frame" x="276" y="0.0" width="40" height="40"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="40" id="SR0-Xr-LNe"/>
-                                <constraint firstAttribute="width" constant="40" id="zIs-lk-2mh"/>
-                            </constraints>
-                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
-                            <connections>
-                                <action selector="cancleAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="7JR-cS-Y5p"/>
-                            </connections>
-                        </button>
-                    </subviews>
-                    <color key="backgroundColor" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
-                    <constraints>
-                        <constraint firstAttribute="height" constant="311" id="3bE-RT-gdX"/>
-                        <constraint firstAttribute="trailing" secondItem="CTY-Fx-tzH" secondAttribute="trailing" constant="12" id="3jK-yB-ifC"/>
-                        <constraint firstAttribute="width" constant="316" id="5Vp-Nm-Phf"/>
-                        <constraint firstItem="l5g-yG-AJ9" firstAttribute="leading" secondItem="crp-Dg-bEh" secondAttribute="leading" constant="12" id="GQX-dv-RhD"/>
-                        <constraint firstItem="CTY-Fx-tzH" firstAttribute="leading" secondItem="crp-Dg-bEh" secondAttribute="leading" constant="12" id="Iin-w2-S5a"/>
-                        <constraint firstItem="mxv-fX-f3j" firstAttribute="centerX" secondItem="crp-Dg-bEh" secondAttribute="centerX" id="J6H-Ym-4wW"/>
-                        <constraint firstAttribute="trailing" secondItem="uSL-RT-oX5" secondAttribute="trailing" constant="10" id="JvH-Ld-uxt"/>
-                        <constraint firstItem="8mM-Qw-PGH" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" id="P4Y-hH-uUz"/>
-                        <constraint firstItem="l5g-yG-AJ9" firstAttribute="top" secondItem="CTY-Fx-tzH" secondAttribute="bottom" constant="12" id="Wuw-qP-DaP"/>
-                        <constraint firstItem="te4-O1-RAs" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" constant="15" id="ci5-BA-awW"/>
-                        <constraint firstAttribute="trailing" secondItem="l5g-yG-AJ9" secondAttribute="trailing" constant="12" id="cye-KU-jSS"/>
-                        <constraint firstAttribute="trailing" secondItem="8mM-Qw-PGH" secondAttribute="trailing" id="ehJ-JA-HqW"/>
-                        <constraint firstItem="uSL-RT-oX5" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" constant="11" id="nwL-G4-dhm"/>
-                        <constraint firstItem="CTY-Fx-tzH" firstAttribute="top" secondItem="te4-O1-RAs" secondAttribute="bottom" constant="15" id="tfs-D8-BNT"/>
-                        <constraint firstAttribute="bottom" secondItem="mxv-fX-f3j" secondAttribute="bottom" constant="18" id="vf5-JM-3n3"/>
-                        <constraint firstItem="te4-O1-RAs" firstAttribute="centerX" secondItem="crp-Dg-bEh" secondAttribute="centerX" id="xB7-AF-HP0"/>
-                    </constraints>
-                    <userDefinedRuntimeAttributes>
-                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
-                            <real key="value" value="12"/>
-                        </userDefinedRuntimeAttribute>
-                    </userDefinedRuntimeAttributes>
-                </view>
-            </subviews>
-            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
-            <constraints>
-                <constraint firstItem="crp-Dg-bEh" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Q7S-rU-daX"/>
-                <constraint firstItem="crp-Dg-bEh" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="l1H-ZN-yAQ"/>
-            </constraints>
-            <nil key="simulatedTopBarMetrics"/>
-            <nil key="simulatedBottomBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <connections>
-                <outlet property="backView" destination="34Q-Ap-BhT" id="gb9-fd-tha"/>
-                <outlet property="countLabel" destination="em6-7z-Xgu" id="poA-O7-hZg"/>
-                <outlet property="musicImage" destination="VVv-Nb-ldQ" id="eG2-FL-W0e"/>
-                <outlet property="musicName" destination="ETV-b6-Fe7" id="Hsg-K4-GTb"/>
-                <outlet property="sureButton" destination="mxv-fX-f3j" id="vDY-eb-vr1"/>
-                <outlet property="textView" destination="WQ8-cQ-EDG" id="kSY-Qo-oPM"/>
-                <outlet property="tipsLabel" destination="9AA-e2-K2q" id="OB0-RH-UrS"/>
-                <outlet property="userName" destination="9Ss-uK-g79" id="9lr-IP-EcM"/>
-            </connections>
-            <point key="canvasLocation" x="121.37404580152672" y="-23.239436619718312"/>
-        </view>
-    </objects>
-    <resources>
-        <image name="cancle_button" width="20" height="20"/>
-        <image name="music_coverBg" width="54" height="54"/>
-        <image name="pub_music_placeholder" width="205" height="205"/>
-        <image name="unChoose_status" width="18" height="18"/>
-        <systemColor name="systemBackgroundColor">
-            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
-        </systemColor>
-    </resources>
-</document>

+ 4 - 5
KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/MediaEditor/KSMediaEditor.m

@@ -244,7 +244,7 @@
 
    
     //导出
-    [self sessionExportAction:mixComposition outputPath:[self getVideoOutputPath] presetName:AVAssetExportPresetMediumQuality outputFileType:AVFileTypeQuickTimeMovie audioMix:audioMix completion:^(NSString *outPath, BOOL isSuccess, NSString *desc) {
+    [self sessionExportAction:mixComposition outputPath:[self getVideoOutputPath] presetName:AVAssetExportPreset1280x720 outputFileType:AVFileTypeQuickTimeMovie audioMix:audioMix completion:^(NSString *outPath, BOOL isSuccess, NSString *desc) {
         completionHandle(outPath, isSuccess, desc);
     }];
     
@@ -293,14 +293,13 @@
     
     // 合成
     AVAssetTrack *recordAssetTrack = [[recordAsset tracksWithMediaType:AVMediaTypeAudio] firstObject];
-    // 录音文件
-    [recordCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, recordAsset.duration) ofTrack:recordAssetTrack atTime:kCMTimeZero error:nil];
+
     // 如果时长超过视频的时长
     CMTime duration = recordDuration > videoDuration ? recordAsset.duration : videoAsset.duration;
     if (recordDuration > videoDuration) {
         duration = videoAsset.duration;
     }
-    
+    // 录音文件
     [recordCompositionTrack insertTimeRange:CMTimeRangeMake(kCMTimeZero, duration) ofTrack:recordAssetTrack atTime:kCMTimeZero error:nil];
     
     AVMutableAudioMixInputParameters *newRecordInputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:recordCompositionTrack];
@@ -308,7 +307,7 @@
     [newRecordInputParams setVolume:recordVolume atTime:kCMTimeZero];
     audioMix.inputParameters = [NSArray arrayWithObjects:newRecordInputParams,nil];
     //导出
-    [self sessionExportAction:mixComposition outputPath:[self getVideoOutputPath] presetName:AVAssetExportPresetMediumQuality outputFileType:AVFileTypeQuickTimeMovie audioMix:audioMix completion:^(NSString *outPath, BOOL isSuccess, NSString *desc) {
+    [self sessionExportAction:mixComposition outputPath:[self getVideoOutputPath] presetName:AVAssetExportPreset1280x720 outputFileType:AVFileTypeQuickTimeMovie audioMix:audioMix completion:^(NSString *outPath, BOOL isSuccess, NSString *desc) {
         completionHandle(outPath, isSuccess, desc);
     }];
 }

+ 0 - 1
KulexiuForTeacher/KulexiuForTeacher/Common/Tools/Custom/PressRecord/KSAudioRecordManager.m

@@ -92,7 +92,6 @@
         AudioQueueAllocateBuffer(audioQRef, bufferByteSize, &audioBuffers[i]);
         AudioQueueEnqueueBuffer(audioQRef, audioBuffers[i], 0, NULL);
     }
-    
 }
 
 - (int)computeRecordBufferSize:(const AudioStreamBasicDescription*)format seconds:(float)seconds

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Common/Tools/GifRefresh/KSGifRefreshHeader.h

@@ -12,6 +12,7 @@ NS_ASSUME_NONNULL_BEGIN
 
 @interface KSGifRefreshHeader : MJRefreshGifHeader
 
+
 @end
 
 NS_ASSUME_NONNULL_END

+ 7 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Controller/MineViewController.m

@@ -38,6 +38,7 @@
 #import "CoursewareViewController.h"
 #import "MineDescView.h"
 #import "TenantMineHeadView.h"
+#import "MineWorksViewController.h"
 
 @interface MineViewController ()<UIScrollViewDelegate>
 
@@ -526,6 +527,12 @@
             [self.navigationController pushViewController:ctrl animated:YES];
         }
             break;
+        case MINEVIEWTYPE_WORKS: // 我的作品
+        {
+            MineWorksViewController *ctrl = [[MineWorksViewController alloc] init];
+            [self.navigationController pushViewController:ctrl animated:YES];
+        }
+            break;
         default:
             break;
     }

+ 1 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/View/MineActionView.h

@@ -39,6 +39,7 @@ typedef NS_ENUM(NSInteger, MINEVIEWTYPE) {
     MINEVIEWTYPE_UPLOADMUSIC, // 上传曲谱
     MINEVIEWTYPE_AWARD,
     MINENAVATYPE_COURSEWARE,  // 课件
+    MINEVIEWTYPE_WORKS,       // 我的作品
 };
 
 #define FUNCTIONVIEW_WIDTH (80)

+ 6 - 3
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/View/MineFunctionView.m

@@ -78,26 +78,29 @@
 
 
 - (CGFloat)getViewHeight {
+    if (self.isMember && self.isSettlement) {
+        return 333.0f;
+    }
     return 232.0f;
 }
 
 - (NSMutableArray *)imageArray {
     if (!_imageArray) {
-        _imageArray = [NSMutableArray arrayWithArray:@[@"tool_minePage",@"tool_mineIncome",@"tool_mineStyle",@"tool_goodsOrder",@"tool_myCourse",@"tool_ticket",@"tool_myMusic",@"tool_uploadMusic"]];
+        _imageArray = [NSMutableArray arrayWithArray:@[@"tool_minePage",@"tool_mineIncome",@"tool_mineStyle",@"tool_goodsOrder",@"tool_myCourse",@"tool_ticket",@"tool_myMusic",@"tool_uploadMusic",@"mine_musicProduct"]];
     }
     return _imageArray;
 }
 
 - (NSMutableArray *)titleArray {
     if (!_titleArray) {
-        _titleArray = [NSMutableArray arrayWithArray:@[@"我的主页",@"我的收入",@"个人风采",@"我的订单",@"我的课程",@"我的优惠券",@"我的乐谱",@"上传曲谱"]];
+        _titleArray = [NSMutableArray arrayWithArray:@[@"我的主页",@"我的收入",@"个人风采",@"我的订单",@"我的课程",@"我的优惠券",@"我的乐谱",@"上传曲谱",@"我的作品"]];
     }
     return _titleArray;
 }
 
 - (NSMutableArray *)tagArray {
     if (!_tagArray) {
-        _tagArray = [NSMutableArray arrayWithArray:@[@(MINEVIEWTYPE_HOMEPAGE),@(MINEVIEWTYPE_INCOME),@(MINEVIEWTYPE_MIEN),@(MINEVIEWTYPE_ORDER),@(MINEVIEWTYPE_FINISHCOURSE),@(MINEVIEWTYPE_TICKET),@(MINEVIEWTYPE_MUSIC),@(MINEVIEWTYPE_UPLOADMUSIC)]];
+        _tagArray = [NSMutableArray arrayWithArray:@[@(MINEVIEWTYPE_HOMEPAGE),@(MINEVIEWTYPE_INCOME),@(MINEVIEWTYPE_MIEN),@(MINEVIEWTYPE_ORDER),@(MINEVIEWTYPE_FINISHCOURSE),@(MINEVIEWTYPE_TICKET),@(MINEVIEWTYPE_MUSIC),@(MINEVIEWTYPE_UPLOADMUSIC),@(MINEVIEWTYPE_WORKS)]];
     }
     return _tagArray;
 }

+ 8 - 10
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/View/MineFunctionView.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -11,11 +11,11 @@
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
         <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MineFunctionView">
-            <rect key="frame" x="0.0" y="0.0" width="414" height="232"/>
+            <rect key="frame" x="0.0" y="0.0" width="414" height="323"/>
             <autoresizingMask key="autoresizingMask"/>
             <subviews>
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="udr-ER-Hx8">
-                    <rect key="frame" x="14" y="0.0" width="386" height="220"/>
+                    <rect key="frame" x="14" y="0.0" width="386" height="311"/>
                     <subviews>
                         <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="常用工具" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ui4-g9-9PK">
                             <rect key="frame" x="15" y="15" width="66" height="22"/>
@@ -27,18 +27,16 @@
                             <nil key="highlightedColor"/>
                         </label>
                         <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bvI-Ts-PIq">
-                            <rect key="frame" x="0.0" y="39" width="386" height="180"/>
+                            <rect key="frame" x="0.0" y="39" width="386" height="270"/>
                             <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="180" id="AbG-kn-eHC"/>
-                            </constraints>
                         </view>
                     </subviews>
                     <color key="backgroundColor" systemColor="systemBackgroundColor"/>
                     <constraints>
+                        <constraint firstItem="bvI-Ts-PIq" firstAttribute="top" secondItem="Ui4-g9-9PK" secondAttribute="bottom" constant="2" id="JLW-8P-MK8"/>
                         <constraint firstItem="Ui4-g9-9PK" firstAttribute="leading" secondItem="udr-ER-Hx8" secondAttribute="leading" constant="15" id="Uux-HL-mf0"/>
                         <constraint firstItem="bvI-Ts-PIq" firstAttribute="leading" secondItem="udr-ER-Hx8" secondAttribute="leading" id="bc5-6r-wX2"/>
-                        <constraint firstItem="bvI-Ts-PIq" firstAttribute="top" secondItem="Ui4-g9-9PK" secondAttribute="bottom" constant="2" id="ghc-C9-1XU"/>
+                        <constraint firstAttribute="bottom" secondItem="bvI-Ts-PIq" secondAttribute="bottom" constant="2" id="jNR-7e-N7R"/>
                         <constraint firstAttribute="trailing" secondItem="bvI-Ts-PIq" secondAttribute="trailing" id="rCL-8d-7w1"/>
                         <constraint firstItem="Ui4-g9-9PK" firstAttribute="top" secondItem="udr-ER-Hx8" secondAttribute="top" constant="15" id="wkM-TY-7p6"/>
                     </constraints>
@@ -62,7 +60,7 @@
             <connections>
                 <outlet property="containerView" destination="bvI-Ts-PIq" id="Ziy-GB-p1n"/>
             </connections>
-            <point key="canvasLocation" x="131.8840579710145" y="23.4375"/>
+            <point key="canvasLocation" x="131.8840579710145" y="53.90625"/>
         </view>
     </objects>
     <resources>

+ 5 - 7
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/View/MineTeachToolView.xib

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <device id="retina6_1" orientation="portrait" appearance="light"/>
     <dependencies>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
         <capability name="System colors in document resources" minToolsVersion="11.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
@@ -11,11 +11,11 @@
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
         <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
         <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MineTeachToolView">
-            <rect key="frame" x="0.0" y="0.0" width="414" height="333"/>
+            <rect key="frame" x="0.0" y="0.0" width="414" height="323"/>
             <autoresizingMask key="autoresizingMask"/>
             <subviews>
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Cfv-vw-6v1">
-                    <rect key="frame" x="14" y="0.0" width="386" height="323"/>
+                    <rect key="frame" x="14" y="0.0" width="386" height="313"/>
                     <subviews>
                         <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="教学工具" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nZ1-d4-AfB">
                             <rect key="frame" x="15" y="15" width="66" height="22"/>
@@ -29,9 +29,6 @@
                         <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tlw-1g-041">
                             <rect key="frame" x="0.0" y="39" width="386" height="270"/>
                             <color key="backgroundColor" systemColor="systemBackgroundColor"/>
-                            <constraints>
-                                <constraint firstAttribute="height" constant="270" id="A2T-RF-Ade"/>
-                            </constraints>
                         </view>
                     </subviews>
                     <color key="backgroundColor" systemColor="systemBackgroundColor"/>
@@ -40,6 +37,7 @@
                         <constraint firstAttribute="trailing" secondItem="tlw-1g-041" secondAttribute="trailing" id="F69-AE-sxv"/>
                         <constraint firstItem="nZ1-d4-AfB" firstAttribute="leading" secondItem="Cfv-vw-6v1" secondAttribute="leading" constant="15" id="GY2-oA-WeB"/>
                         <constraint firstItem="tlw-1g-041" firstAttribute="leading" secondItem="Cfv-vw-6v1" secondAttribute="leading" id="OWt-vG-AmF"/>
+                        <constraint firstAttribute="bottom" secondItem="tlw-1g-041" secondAttribute="bottom" constant="4" id="XXg-Zi-k3e"/>
                         <constraint firstItem="tlw-1g-041" firstAttribute="top" secondItem="nZ1-d4-AfB" secondAttribute="bottom" constant="2" id="icF-If-FIX"/>
                     </constraints>
                     <userDefinedRuntimeAttributes>

+ 10 - 4
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/Controller/KSDraftMergeViewController.m

@@ -15,6 +15,8 @@
 
 @property (nonatomic, copy) DraftEditCallback callback;
 
+@property (nonatomic, assign) BOOL hasInitUI;
+
 @end
 
 @implementation KSDraftMergeViewController
@@ -51,9 +53,11 @@
     [super viewDidLoad];
     // Do any additional setup after loading the view.
     self.ks_prefersNavigationBarHidden = YES;
+    self.hasInitUI = NO;
 }
 
 - (void)configUI {
+    self.hasInitUI = YES;
     [self.scrollView removeFromSuperview];
     KSMediaMergeView *mergeView = [[KSMediaMergeView alloc] init];
     mergeView.coverImage = self.sourceModel.img;
@@ -93,10 +97,12 @@
 - (void)viewDidAppear:(BOOL)animated {
     [super viewDidAppear:animated];
     [self changeOrientation:YES];
-    // 切换到横屏
-    dispatch_delay_block(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC), ^{
-        [self configUI];
-    });
+    if (self.hasInitUI == NO) {
+        // 切换到横屏
+        dispatch_delay_block(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC), ^{
+            [self configUI];
+        });
+    }
 }
 
 

+ 26 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/Controller/KSVideoCropViewController.h

@@ -0,0 +1,26 @@
+//
+//  KSVideoCropViewController.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "KSBaseViewController.h"
+
+typedef void(^VideoCropCallback)(UIImage * _Nonnull cropImage);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSVideoCropViewController : KSBaseViewController
+
+- (void)configWithVideoPath:(NSURL *)videoPathUrl;
+
+- (void)configWithVideoRemoteUrl:(NSString *)remoteUrl;
+
+- (void)chooseCropImageCallback:(VideoCropCallback)callback;
+
+- (void)changeLandScape;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 253 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/Controller/KSVideoCropViewController.m

@@ -0,0 +1,253 @@
+//
+//  KSVideoCropViewController.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "KSVideoCropViewController.h"
+#import <AVFoundation/AVFoundation.h>
+#import "KSCropImageNavView.h"
+#import "KSVideoImageSlider.h"
+#import "AppDelegate+AppService.h"
+#import "UIDevice+TFDevice.h"
+
+
+#define COVER_COUNT (10)
+
+@interface KSVideoCropViewController ()
+
+@property (nonatomic, strong) KSCropImageNavView *navView;
+
+@property (nonatomic, strong) UIImageView *displayImage;
+
+@property (strong,nonatomic)AVAssetImageGenerator * imageGenerator;
+
+@property (strong, nonatomic)NSMutableArray * imageArray;
+
+@property (nonatomic, strong) NSURL *videoUrl;
+
+@property (nonatomic, copy) VideoCropCallback callback;
+
+@property (nonatomic, strong) KSVideoImageSlider *imageSlider;
+
+@property (nonatomic, assign) BOOL needChangeOrigin;
+@end
+
+@implementation KSVideoCropViewController
+
+- (void)changeOrientation:(BOOL)isLandScape {
+    if (isLandScape) {
+        // 切换到横屏
+        AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
+        delegate.allowAutoRotate = YES;
+        [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeRight inController:self];
+    }
+    else {
+        
+        AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
+        delegate.allowAutoRotate = NO;
+        [UIDevice switchNewOrientation:UIInterfaceOrientationPortrait inController:self];
+    }
+}
+
+- (void)viewDidLoad {
+    [super viewDidLoad];
+    // Do any additional setup after loading the view.
+    [self configUI];
+}
+
+- (void)changeLandScape {
+    self.needChangeOrigin = YES;
+    [self changeOrientation:YES];
+}
+
+- (void)configUI {
+    self.ks_prefersNavigationBarHidden = YES;
+    [self.view addSubview:self.displayImage];
+    [self.displayImage mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.view);
+    }];
+    CGFloat height = 84.0f;
+    [self.view addSubview:self.imageSlider];
+    [self.imageSlider mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.mas_equalTo(self.view.mas_left).offset(iPhoneXSafeTopMargin);
+        make.right.mas_equalTo(self.view.mas_right).offset(-iPhoneXSafeBottomMargin);
+        make.bottom.mas_equalTo(self.view.mas_bottom).offset(-iPhoneXSafeBottomMargin);
+        make.height.mas_equalTo(height);
+    }];
+    
+    CGFloat navHeight = [KSCropImageNavView getViewHeight];
+    [self.view addSubview:self.navView];
+    [self.navView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.mas_equalTo(self.view);
+        make.height.mas_equalTo(navHeight);
+    }];
+}
+
+- (void)configWithVideoPath:(NSURL *)videoPathUrl {
+    [self configImageWallWithPath:videoPathUrl];
+}
+
+- (void)configImageWallWithPath:(NSURL *)fileUrl {
+    self.videoUrl = fileUrl;
+    AVAsset * asset =[AVAsset assetWithURL:fileUrl];
+    NSMutableArray * times = [NSMutableArray arrayWithCapacity:0];
+    CGFloat videoTime = CMTimeGetSeconds(asset.duration);
+
+    for (int i = 0; i < COVER_COUNT; i++) {
+        
+        CMTime time = [asset duration];
+        long long duration = time.value;
+        time.value = (i*1.0) / COVER_COUNT * duration;
+        NSValue * timeValue = [NSValue valueWithCMTime:time];
+        [times addObject:timeValue];
+    }
+    
+    if (_imageGenerator == nil) {
+        _imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset];
+        _imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
+        _imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
+        _imageGenerator.appliesPreferredTrackTransform = YES;
+    }
+    if (_imageArray == nil) {
+        _imageArray = [NSMutableArray arrayWithCapacity:0];
+    }
+
+    __block NSInteger count = 0;
+    AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){
+        if (result == AVAssetImageGeneratorSucceeded) {
+            UIImage *thumbnail = [UIImage imageWithCGImage:im];
+            [self.imageArray addObject:thumbnail];
+            count ++;
+        }
+        else if(result == AVAssetImageGeneratorFailed){
+            count ++;
+            NSLog(@">>>>>>>>>>>generate failed");
+        }
+        else if(result == AVAssetImageGeneratorCancelled){
+            count ++;
+            NSLog(@">>>>>>>>>>>generate cancelled");
+        }
+        if (count == times.count) {
+            [self performSelector:@selector(updateStatus:) onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO];
+        }
+    };
+    
+    _imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
+    _imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
+    [_imageGenerator generateCGImagesAsynchronouslyForTimes:times completionHandler:handler];
+}
+
+- (void)updateStatus:(id)sender {
+    self.imageSlider.maximumValue = _imageArray.count;
+    UIImage *firstImage = [self.imageArray firstObject];
+    self.imageSlider.imageArray = [self.imageArray copy];
+    [self.imageSlider createTheImageWall];
+    [self.imageSlider updateTheKnobImage:firstImage];
+    [self.displayImage setImage:firstImage];
+}
+
+- (void)configWithVideoRemoteUrl:(NSString *)remoteUrl {
+    [LOADING_MANAGER showCustomLoading:@"资源下载中..."];
+    [KSNetworkingManager downloadFileRequestWithFileUrl:remoteUrl progress:^(int64_t bytesRead, int64_t totalBytes) {
+
+    } success:^(NSURL * _Nonnull fileUrl) {
+        [LOADING_MANAGER removeCustomLoading];
+        [self configImageWallWithPath:fileUrl];
+        
+    } faliure:^(NSError * _Nonnull error) {
+        [LOADING_MANAGER removeCustomLoading];
+    }];
+}
+
+- (void)chooseCropImageCallback:(VideoCropCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+- (void)slideValueChanged:(id)control{
+    KSVideoImageSlider* slider = (KSVideoImageSlider*)control;
+    float scale = slider.knobValue/self.imageArray.count;
+    UIImage * image = [self generateThumbImageWithTime:scale];
+    [slider updateTheKnobImage:image];
+    [self.displayImage setImage:image];
+    NSLog(@">>>>>>>>>>>>%f ----- scale %f ",slider.knobValue,  scale);
+}
+
+
+- (UIImage *)generateThumbImageWithTime:(CGFloat)progress {
+    NSURL *url = self.videoUrl;
+    AVAsset *asset = [AVAsset assetWithURL:url];
+    if (_imageGenerator == nil) {
+        _imageGenerator = [[AVAssetImageGenerator alloc]initWithAsset:asset];
+        _imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
+        _imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
+        _imageGenerator.appliesPreferredTrackTransform = YES;
+    }
+    CMTime time = [asset duration];
+    long long duration = time.value;
+    time.value = progress*duration;
+    
+    CGImageRef imageRef = [_imageGenerator copyCGImageAtTime:time actualTime:NULL error:NULL];
+    UIImage *thumbnail = [UIImage imageWithCGImage:imageRef];
+    // CGImageRef won't be released by ARC, so you must release.
+    CGImageRelease(imageRef);
+    
+    return thumbnail;
+}
+#pragma mark ---- lazying
+- (UIImageView *)displayImage {
+    if (!_displayImage) {
+        _displayImage = [[UIImageView alloc] init];
+    }
+    return _displayImage;
+}
+
+- (KSVideoImageSlider *)imageSlider {
+    if (!_imageSlider) {
+        _imageSlider = [[KSVideoImageSlider alloc] initWithFrame:CGRectMake(0, 0, KLandscapeWidth - iPhoneXSafeTopMargin - iPhoneXSafeBottomMargin, 84)];
+        [_imageSlider addTarget:self
+                         action:@selector(slideValueChanged:)
+               forControlEvents:UIControlEventValueChanged];
+    }
+    return _imageSlider;
+}
+
+- (KSCropImageNavView *)navView {
+    if (!_navView) {
+        _navView = [KSCropImageNavView shareInstance];
+        MJWeakSelf;
+        [_navView navAction:^(BOOL isBack) {
+            if (isBack) {
+                [weakSelf backAction];
+            }
+            else {
+                if (weakSelf.needChangeOrigin) {
+                    [weakSelf changeOrientation:NO];
+                }
+                if (weakSelf.callback) {
+                    weakSelf.callback(weakSelf.displayImage.image);
+                }
+                [weakSelf backAction];
+            }
+        }];
+    }
+    return _navView;
+}
+
+
+- (void)backAction {
+    [self dismissViewControllerAnimated:YES completion:nil];
+}
+/*
+#pragma mark - Navigation
+
+// In a storyboard-based application, you will often want to do a little preparation before navigation
+- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
+    // Get the new view controller using [segue destinationViewController].
+    // Pass the selected object to the new view controller.
+}
+*/
+
+@end

+ 9 - 7
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/Controller/MineWorksViewController.m

@@ -67,11 +67,10 @@
     self.categoryView.titleColor = HexRGB(0x777777);
     self.categoryView.titleColorGradientEnabled = YES;
     
-    JXCategoryIndicatorLineView *lineView = [[JXCategoryIndicatorLineView alloc] init];
-    lineView.indicatorColor = HexRGB(0x2DC7AA);
-    lineView.indicatorWidth = 16;
-    lineView.height = 4;
-    lineView.verticalMargin = 5;
+    JXCategoryIndicatorImageView *lineView = [[JXCategoryIndicatorImageView alloc] init];
+    [lineView.indicatorImageView setImage:[UIImage imageNamed:@"minework_Line"]];
+    lineView.indicatorImageViewSize = CGSizeMake(16, 4);
+    lineView.verticalMargin = 10;
     self.categoryView.indicators = @[lineView];
     
     _pagerView = [self preferredPagingView];
@@ -98,8 +97,11 @@
 - (void)viewWillAppear:(BOOL)animated {
     [super viewWillAppear:animated];
     [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
-    if (self.listViewArray.count > self.categoryView.selectedIndex) {
-        id value = self.listViewArray[self.categoryView.selectedIndex];
+    [self refreshAllPage];
+}
+
+- (void)refreshAllPage {
+    for (id value in self.listViewArray) {
         if ([value isKindOfClass:[KSJXBodyView class]]) {
             KSJXBodyView *listView = (KSJXBodyView *)value;
             [listView beginFirstRefresh];

+ 24 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/KSCropImageNavView.h

@@ -0,0 +1,24 @@
+//
+//  KSCropImageNavView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import <UIKit/UIKit.h>
+
+typedef void(^CropNavCallback)(BOOL isBack);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSCropImageNavView : UIView
+
++ (instancetype)shareInstance;
+
+- (void)navAction:(CropNavCallback)callback;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 60 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/KSCropImageNavView.m

@@ -0,0 +1,60 @@
+//
+//  KSCropImageNavView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "KSCropImageNavView.h"
+#import "UIView+KSLayer.h"
+
+@interface KSCropImageNavView ()
+
+@property (weak, nonatomic) IBOutlet UIView *layerView;
+
+@property (nonatomic, copy) CropNavCallback callback;
+
+@end
+
+@implementation KSCropImageNavView
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    CAGradientLayer *titleLayer = [UIView createGradientLayerFromColor:HexRGB(0x0D0D0D) startPoint:CGPointMake(0.5, 0) endColor:HexRGBAlpha(0x000000, 0) endPoint:CGPointMake(0.5, 1) bounds:CGRectMake(0, 0, KLandscapeWidth, [KSCropImageNavView getViewHeight])];
+    [self.layerView.layer addSublayer:titleLayer];
+}
++ (instancetype)shareInstance {
+    KSCropImageNavView *view = [[[NSBundle mainBundle] loadNibNamed:@"KSCropImageNavView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)navAction:(CropNavCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+- (IBAction)backAction:(id)sender {
+    if (self.callback) {
+        self.callback(YES);
+    }
+}
+
+- (IBAction)sureChoose:(id)sender {
+    if (self.callback) {
+        self.callback(NO);
+    }
+}
+
+
++ (CGFloat)getViewHeight {
+    return 59.0f;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 101 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/KSCropImageNavView.xib

@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="KSCropImageNavView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="61"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view alpha="0.59999999999999998" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xeU-Tl-Xhh">
+                    <rect key="frame" x="0.0" y="0.0" width="393" height="61"/>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                </view>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="HJB-he-mP1">
+                    <rect key="frame" x="0.0" y="0.0" width="393" height="61"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="back_button_white" translatesAutoresizingMaskIntoConstraints="NO" id="B8v-QN-Iho">
+                            <rect key="frame" x="20" y="20.666666666666668" width="12" height="20.000000000000004"/>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="401-bU-jDD">
+                            <rect key="frame" x="0.0" y="0.0" width="44" height="61"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="44" id="xF7-tP-bKn"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="backAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="tti-8Q-1As"/>
+                            </connections>
+                        </button>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="编辑封面" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GGz-C6-Tp4">
+                            <rect key="frame" x="163.66666666666666" y="20.666666666666668" width="66" height="20.000000000000004"/>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                            <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dGw-mB-Z1v">
+                            <rect key="frame" x="305" y="14.666666666666664" width="64" height="32"/>
+                            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="64" id="UdM-ZV-lN9"/>
+                                <constraint firstAttribute="height" constant="32" id="k09-mz-AeM"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <state key="normal" title="保存">
+                                <color key="titleColor" red="0.1764705882352941" green="0.7803921568627451" blue="0.66666666666666663" alpha="1" colorSpace="calibratedRGB"/>
+                            </state>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="16"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                            <connections>
+                                <action selector="sureChoose:" destination="iN0-l3-epB" eventType="touchUpInside" id="qFa-pj-gTm"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="GGz-C6-Tp4" firstAttribute="centerX" secondItem="HJB-he-mP1" secondAttribute="centerX" id="Ox9-3S-KJA"/>
+                        <constraint firstAttribute="trailing" secondItem="dGw-mB-Z1v" secondAttribute="trailing" constant="24" id="ZHA-ZL-TIB"/>
+                        <constraint firstItem="B8v-QN-Iho" firstAttribute="leading" secondItem="HJB-he-mP1" secondAttribute="leading" constant="20" id="ZYs-sQ-01o"/>
+                        <constraint firstItem="401-bU-jDD" firstAttribute="leading" secondItem="HJB-he-mP1" secondAttribute="leading" id="dQS-5Y-Zow"/>
+                        <constraint firstItem="GGz-C6-Tp4" firstAttribute="centerY" secondItem="HJB-he-mP1" secondAttribute="centerY" id="e94-GC-ZGQ"/>
+                        <constraint firstItem="401-bU-jDD" firstAttribute="top" secondItem="HJB-he-mP1" secondAttribute="top" id="hql-Xo-4On"/>
+                        <constraint firstItem="B8v-QN-Iho" firstAttribute="centerY" secondItem="HJB-he-mP1" secondAttribute="centerY" id="lOC-f2-ccQ"/>
+                        <constraint firstItem="dGw-mB-Z1v" firstAttribute="centerY" secondItem="HJB-he-mP1" secondAttribute="centerY" id="neX-1C-uUS"/>
+                        <constraint firstAttribute="bottom" secondItem="401-bU-jDD" secondAttribute="bottom" id="rkO-Q4-7Hf"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="HJB-he-mP1" secondAttribute="trailing" id="Awy-71-IeY"/>
+                <constraint firstItem="HJB-he-mP1" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="Hye-1f-zjE"/>
+                <constraint firstItem="xeU-Tl-Xhh" firstAttribute="trailing" secondItem="HJB-he-mP1" secondAttribute="trailing" id="I9Q-Of-9yY"/>
+                <constraint firstItem="xeU-Tl-Xhh" firstAttribute="leading" secondItem="HJB-he-mP1" secondAttribute="leading" id="TCA-gz-2rL"/>
+                <constraint firstItem="HJB-he-mP1" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="cmv-a3-DOt"/>
+                <constraint firstAttribute="bottom" secondItem="HJB-he-mP1" secondAttribute="bottom" id="rJK-wt-q5F"/>
+                <constraint firstItem="xeU-Tl-Xhh" firstAttribute="bottom" secondItem="HJB-he-mP1" secondAttribute="bottom" id="saw-Qt-SH7"/>
+                <constraint firstItem="xeU-Tl-Xhh" firstAttribute="top" secondItem="HJB-he-mP1" secondAttribute="top" id="t5k-js-uGI"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="layerView" destination="xeU-Tl-Xhh" id="eLg-NR-BQt"/>
+            </connections>
+            <point key="canvasLocation" x="64.885496183206101" y="-129.22535211267606"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="back_button_white" width="12" height="20"/>
+    </resources>
+</document>

+ 25 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/KSVideoImageSlider.h

@@ -0,0 +1,25 @@
+//
+//  KSVideoImageSlider.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface KSVideoImageSlider : UIControl
+@property (nonatomic) float maximumValue;
+@property (nonatomic) float minimumValue;
+@property (nonatomic) float knobValue;
+@property (nonatomic,strong)NSMutableArray * imageArray;
+
+//Method
+-(void)createTheImageWall;
+-(void)updateTheKnobImage:(UIImage*)image;
+-(void)moveKnobWithSelectedValue:(float)value;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 133 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/KSVideoImageSlider.m

@@ -0,0 +1,133 @@
+//
+//  KSVideoImageSlider.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "KSVideoImageSlider.h"
+#define BOUND(VALUE, UPPER, LOWER)    MIN(MAX(VALUE, LOWER), UPPER)
+
+@interface KSVideoImageSlider ()
+{
+    UIImageView *_knobView;
+    float _knobWidth;
+    float _knobHeight;
+    float _useableTrackLength;
+    CGPoint _previousTouchPoint;
+}
+
+
+@end
+
+@implementation KSVideoImageSlider
+
+- (id)initWithFrame:(CGRect)frame
+{
+    self = [super initWithFrame:frame];
+    if (self) {
+        // Initialization code
+        _maximumValue = 10.0;
+        _minimumValue = 0.0;
+       // _knobValue = 0.0;
+        [self createLayerView:frame];
+        [self createTheknob];
+        [self setKnodFrames];
+    }
+    return self;
+}
+
+- (void)createLayerView:(CGRect)frame {
+    UIView *layerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
+    layerView.backgroundColor = [UIColor blackColor];
+    layerView.alpha = 0.32;
+    layerView.userInteractionEnabled = NO;
+    [self addSubview:layerView];
+}
+
+#pragma mark   --------PublicMethod
+-(void)createTheImageWall {
+    for (int i=0; i<self.maximumValue; i++) {
+        UIImageView * imageView = [[UIImageView alloc]initWithFrame:CGRectMake(i*(self.frame.size.width/self.maximumValue), 2, self.frame.size.width/self.maximumValue, self.frame.size.height-4)];
+        UIImage *image = self.imageArray[i];
+        [imageView setImage:image];
+        [self addSubview:imageView];
+        [self sendSubviewToBack:imageView];
+    }
+}
+
+- (void)updateTheKnobImage:(UIImage*)image{
+    [_knobView setImage:image];
+}
+
+- (void)moveKnobWithSelectedValue:(float)value{
+    [self setKnobValue:value];
+    [self setKnodFrames];
+}
+#pragma mark  --------PrivateMethod
+- (void)createTheknob{
+    if (_knobView == nil) {
+        _knobView = [[UIImageView alloc]init];
+        _knobView.layer.cornerRadius = 10.0f;
+        _knobView.layer.borderColor = HexRGB(0x279FFE).CGColor;
+        _knobView.layer.borderWidth = 4.0f;
+        _knobView.layer.masksToBounds = YES;
+        _knobView.contentMode = UIViewContentModeScaleAspectFill;
+        [self addSubview:_knobView];
+        [self bringSubviewToFront:_knobView];
+    }
+}
+
+- (void) setKnodFrames {
+    _knobWidth = 128;
+    _knobHeight = self.bounds.size.height;
+    _useableTrackLength = self.bounds.size.width - _knobWidth;
+    
+    float knobCentre = [self positionForValue:self.knobValue];
+    _knobView.frame = CGRectMake(knobCentre - _knobWidth / 2, 0, _knobWidth, _knobHeight);
+}
+
+- (float)positionForValue:(float)value
+{
+    return _useableTrackLength * (value - _minimumValue) /
+    (_maximumValue - _minimumValue) + (_knobWidth / 2);
+}
+#pragma mark -----------TouchHandle
+- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{
+    _previousTouchPoint = [touch locationInView:self];
+    
+    return YES;
+}
+- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{
+    CGPoint touchPoint = [touch locationInView:self];
+    
+    // 1. determine by how much the user has dragged
+    float delta = touchPoint.x - _previousTouchPoint.x;
+    float valueDelta = (_maximumValue - _minimumValue) * delta / _useableTrackLength;
+    
+    _previousTouchPoint = touchPoint;
+    
+    _knobValue  += valueDelta;
+    _knobValue  = BOUND(_knobValue, _maximumValue, _minimumValue);
+    [CATransaction begin];
+    [CATransaction setDisableActions:YES] ;
+    
+    [self setKnodFrames];
+    
+    [CATransaction commit];
+    [self sendActionsForControlEvents:UIControlEventValueChanged];
+    return YES;
+}
+
+- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{
+    
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MineWorksBodyView.m

@@ -238,7 +238,7 @@
     ctrl.sourceModel = model;
     MJWeakSelf;
     [ctrl editCallback:^{
-        [weakSelf refreshAndRequestData];
+//        [weakSelf refreshAndRequestData];
     }];
     [self.naviController pushViewController:ctrl animated:YES];
 }

+ 1 - 1
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MineWorksNavView.m

@@ -24,7 +24,7 @@
     [super awakeFromNib];
     self.editView.hidden = YES;
     self.editButton.userInteractionEnabled = NO;
-    CAGradientLayer *titleLayer = [UIView createGradientLayerFromColor:HexRGBAlpha(0x77FFEF, 0.59) startPoint:CGPointMake(0.89, 1) endColor:HexRGB(0x42CDFF) endPoint:CGPointMake(0.19, 1) bounds:CGRectMake(0, 0, 48, 6)];
+    CAGradientLayer *titleLayer = [UIView createGradientLayerFromColor:HexRGBAlpha(0x77FFEF, 0.59) startPoint:CGPointMake(0.89, 1) endColor:HexRGB(0x2DC7AA) endPoint:CGPointMake(0.19, 1) bounds:CGRectMake(0, 0, 48, 6)];
     [self.titleView.layer addSublayer:titleLayer];
 }
 + (instancetype)shareInstance {

+ 11 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MineWorksNavView.xib

@@ -16,6 +16,14 @@
                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YPw-d9-Fo2">
                     <rect key="frame" x="0.0" y="57" width="393" height="44"/>
                     <subviews>
+                        <view alpha="0.5" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9jc-v6-Eln">
+                            <rect key="frame" x="51" y="30" width="48" height="6"/>
+                            <color key="backgroundColor" red="0.46666666670000001" green="1" blue="0.93725490199999995" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="48" id="PFz-l9-lLX"/>
+                                <constraint firstAttribute="height" constant="6" id="WSQ-8a-7uF"/>
+                            </constraints>
+                        </view>
                         <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="mine_worksTitle" translatesAutoresizingMaskIntoConstraints="NO" id="Cum-va-YAQ">
                             <rect key="frame" x="50" y="12" width="78" height="20"/>
                         </imageView>
@@ -85,6 +93,7 @@
                         <constraint firstItem="bO5-ys-7vL" firstAttribute="top" secondItem="YPw-d9-Fo2" secondAttribute="top" id="0Wq-0Z-ESW"/>
                         <constraint firstItem="Cum-va-YAQ" firstAttribute="centerY" secondItem="YPw-d9-Fo2" secondAttribute="centerY" id="5c0-EU-uVv"/>
                         <constraint firstItem="Cum-va-YAQ" firstAttribute="leading" secondItem="71W-r1-CNZ" secondAttribute="trailing" constant="20" id="6pF-6L-JHO"/>
+                        <constraint firstItem="9jc-v6-Eln" firstAttribute="top" secondItem="Cum-va-YAQ" secondAttribute="bottom" constant="-2" id="Aqt-dj-dQZ"/>
                         <constraint firstItem="ENM-WF-Mzx" firstAttribute="bottom" secondItem="ts0-Ql-G2n" secondAttribute="bottom" id="J3e-3M-SLR"/>
                         <constraint firstItem="bO5-ys-7vL" firstAttribute="leading" secondItem="YPw-d9-Fo2" secondAttribute="leading" id="YX4-Vs-gxk"/>
                         <constraint firstItem="71W-r1-CNZ" firstAttribute="leading" secondItem="YPw-d9-Fo2" secondAttribute="leading" constant="18" id="dEF-TC-40s"/>
@@ -95,6 +104,7 @@
                         <constraint firstItem="ENM-WF-Mzx" firstAttribute="trailing" secondItem="ts0-Ql-G2n" secondAttribute="trailing" id="rXf-oC-R77"/>
                         <constraint firstItem="ENM-WF-Mzx" firstAttribute="top" secondItem="ts0-Ql-G2n" secondAttribute="top" id="suh-Ms-LBC"/>
                         <constraint firstAttribute="bottom" secondItem="bO5-ys-7vL" secondAttribute="bottom" id="vYe-gB-vjw"/>
+                        <constraint firstItem="9jc-v6-Eln" firstAttribute="leading" secondItem="Cum-va-YAQ" secondAttribute="leading" constant="1" id="z7b-l3-TOs"/>
                     </constraints>
                 </view>
             </subviews>
@@ -111,6 +121,7 @@
                 <outlet property="editButton" destination="ENM-WF-Mzx" id="LPu-MD-8tm"/>
                 <outlet property="editLabel" destination="C2M-qv-DUp" id="Uc0-eX-7lP"/>
                 <outlet property="editView" destination="ts0-Ql-G2n" id="mAx-AK-7hI"/>
+                <outlet property="titleView" destination="9jc-v6-Eln" id="4zd-LC-8Wu"/>
             </connections>
             <point key="canvasLocation" x="52.671755725190835" y="-5.2816901408450709"/>
         </view>

+ 21 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPubHeader.h

@@ -0,0 +1,21 @@
+//
+//  MusicPubHeader.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#ifndef MusicPubHeader_h
+#define MusicPubHeader_h
+
+typedef NS_ENUM(NSInteger, PUBLISH_ACTION) {
+    PUBLISH_ACTION_CHOOSEIMG,  // 选择作品封面
+    PUBLISH_ACTION_PUBLISH,    // 发布
+    PUBLISH_ACTION_VIDEOCOVER, // 选择视频封面
+    PUBLISH_ACTION_VIDEOCROP,  // 截取视频封面
+};
+
+typedef void(^MusicPublishCallback)(PUBLISH_ACTION type);
+
+
+#endif /* MusicPubHeader_h */

+ 7 - 12
KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/MusicPublistAlert.h → KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublicContentView.h

@@ -1,22 +1,16 @@
 //
-//  MusicPublistAlert.h
+//  MusicPublicContentView.h
 //  KulexiuSchoolStudent
 //
-//  Created by 王智 on 2023/11/1.
+//  Created by 王智 on 2023/11/8.
 //
 
 #import <UIKit/UIKit.h>
-
-typedef NS_ENUM(NSInteger, PUBLISH_ACTION) {
-    PUBLISH_ACTION_CHOOSEIMG,
-    PUBLISH_ACTION_PUBLISH,
-};
-
-typedef void(^MusicPublishCallback)(PUBLISH_ACTION type);
+#import "MusicPubHeader.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
-@interface MusicPublistAlert : UIView
+@interface MusicPublicContentView : UIView
 
 @property (weak, nonatomic) IBOutlet UITextView *textView;
 
@@ -28,9 +22,10 @@ NS_ASSUME_NONNULL_BEGIN
 
 + (instancetype)shareInstance;
 
-- (void)chooseAction:(MusicPublishCallback)callback;
+- (void)musicContentPubAction:(MusicPublishCallback)callback;
+
++ (CGFloat)getViewHeight;
 
-- (void)showAlert;
 @end
 
 NS_ASSUME_NONNULL_END

+ 15 - 24
KulexiuForTeacher/KulexiuForTeacher/Common/MediaMerge/AudioMerge/MusicPublistAlert.m → KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublicContentView.m

@@ -1,39 +1,42 @@
 //
-//  MusicPublistAlert.m
+//  MusicPublicContentView.m
 //  KulexiuSchoolStudent
 //
-//  Created by 王智 on 2023/11/1.
+//  Created by 王智 on 2023/11/8.
 //
 
-#import "MusicPublistAlert.h"
-#import "UIView+KSLayer.h"
+#import "MusicPublicContentView.h"
 
-@interface MusicPublistAlert ()<UITextViewDelegate>
+@interface MusicPublicContentView ()<UITextViewDelegate>
 
 @property (weak, nonatomic) IBOutlet UIButton *sureButton;
 
 @property (weak, nonatomic) IBOutlet UILabel *countLabel;
 
 @property (weak, nonatomic) IBOutlet UILabel *tipsLabel;
+
 @property (weak, nonatomic) IBOutlet UIView *backView;
 
 @property (nonatomic, copy) MusicPublishCallback callback;
 
 @end
 
-@implementation MusicPublistAlert
+@implementation MusicPublicContentView
+
 - (void)awakeFromNib {
     [super awakeFromNib];
     self.textView.delegate = self;
+    
     self.backView.layer.cornerRadius = 4;
     self.backView.layer.maskedCorners = kCALayerMinXMaxYCorner | kCALayerMaxXMaxYCorner;
 }
+
 + (instancetype)shareInstance {
-    MusicPublistAlert *view = [[[NSBundle mainBundle] loadNibNamed:@"MusicPublistAlert" owner:nil options:nil] firstObject];
+    MusicPublicContentView *view = [[[NSBundle mainBundle] loadNibNamed:@"MusicPublicContentView" owner:nil options:nil] firstObject];
     return view;
 }
 
-- (void)chooseAction:(MusicPublishCallback)callback {
+- (void)musicContentPubAction:(MusicPublishCallback)callback {
     if (callback) {
         self.callback = callback;
     }
@@ -43,30 +46,14 @@
     if (self.callback) {
         self.callback(PUBLISH_ACTION_PUBLISH);
     }
-    [self hideAlert];
 }
 
-- (IBAction)cancleAction:(id)sender {
-    [self hideAlert];
-}
 - (IBAction)chooseCover:(id)sender {
     if (self.callback) {
         self.callback(PUBLISH_ACTION_CHOOSEIMG);
     }
 }
 
-- (void)showAlert {
-    UIWindow *window = [NSObject getKeyWindow];
-    [window addSubview:self];
-    [self mas_makeConstraints:^(MASConstraintMaker *make) {
-        make.left.right.top.bottom.mas_equalTo(window);
-    }];
-}
-
-- (void)hideAlert {
-    [self removeFromSuperview];
-}
-
 #pragma mark   ---- delegate
 
 - (void)textViewDidBeginEditing:(UITextView *)textView {
@@ -97,6 +84,10 @@
     self.countLabel.text = [NSString stringWithFormat:@"%zd/150",newString.length];
     return YES;
 }
+
++ (CGFloat)getViewHeight {
+    return 230.0f;
+}
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.

+ 222 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublicContentView.xib

@@ -0,0 +1,222 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MusicPublicContentView">
+            <rect key="frame" x="0.0" y="0.0" width="393" height="246"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ySm-Or-cry">
+                    <rect key="frame" x="12" y="99" width="369" height="73"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="music_coverBg" translatesAutoresizingMaskIntoConstraints="NO" id="vJP-em-vzJ">
+                            <rect key="frame" x="19" y="6" width="61" height="61"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="61" id="7rv-9b-MmO"/>
+                                <constraint firstAttribute="width" constant="61" id="DAq-YP-o88"/>
+                            </constraints>
+                        </imageView>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="pub_music_placeholder" translatesAutoresizingMaskIntoConstraints="NO" id="IbR-gO-EMr">
+                            <rect key="frame" x="12" y="5.6666666666666714" width="62" height="62"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="62" id="FyK-dq-xsq"/>
+                                <constraint firstAttribute="width" constant="62" id="v2f-ci-KsA"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="8"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Lq4-ga-A7R">
+                            <rect key="frame" x="90" y="20" width="267" height="22"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="22" id="Q4v-O1-QEK"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                            <color key="textColor" red="0.074509803920000006" green="0.078431372550000003" blue="0.08235294118" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="I8N-pM-mro">
+                            <rect key="frame" x="90" y="46" width="267" height="20"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="20" id="NGk-7d-ARq"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.46666666670000001" green="0.46666666670000001" blue="0.46666666670000001" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <imageView hidden="YES" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="unChoose_status" translatesAutoresizingMaskIntoConstraints="NO" id="Z2c-Y5-JPA">
+                            <rect key="frame" x="0.0" y="27.666666666666671" width="0.0" height="18"/>
+                            <constraints>
+                                <constraint firstAttribute="width" id="Hkp-6N-xov"/>
+                                <constraint firstAttribute="height" constant="18" id="ihT-D0-sko"/>
+                            </constraints>
+                        </imageView>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xB0-uR-3Vs">
+                            <rect key="frame" x="12" y="47.666666666666657" width="62" height="20"/>
+                            <subviews>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="选封面" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dcs-Oi-GdD">
+                                    <rect key="frame" x="11" y="0.0" width="40" height="18"/>
+                                    <constraints>
+                                        <constraint firstAttribute="height" constant="18" id="b6r-rS-afy"/>
+                                    </constraints>
+                                    <fontDescription key="fontDescription" type="system" pointSize="13"/>
+                                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                            </subviews>
+                            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.37" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                            <constraints>
+                                <constraint firstItem="Dcs-Oi-GdD" firstAttribute="centerX" secondItem="xB0-uR-3Vs" secondAttribute="centerX" id="0wX-YL-1c6"/>
+                                <constraint firstAttribute="height" constant="20" id="brl-Li-9m9"/>
+                                <constraint firstItem="Dcs-Oi-GdD" firstAttribute="top" secondItem="xB0-uR-3Vs" secondAttribute="top" id="e1c-2K-Qry"/>
+                                <constraint firstAttribute="width" constant="62" id="ls3-YT-lFD"/>
+                            </constraints>
+                        </view>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mGl-dI-rCl">
+                            <rect key="frame" x="12" y="5.6666666666666714" width="62" height="62"/>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="chooseCover:" destination="iN0-l3-epB" eventType="touchUpInside" id="5Fe-41-6ZC"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="IbR-gO-EMr" firstAttribute="centerY" secondItem="ySm-Or-cry" secondAttribute="centerY" id="2m2-TL-KDB"/>
+                        <constraint firstItem="IbR-gO-EMr" firstAttribute="trailing" secondItem="vJP-em-vzJ" secondAttribute="trailing" constant="-6" id="3Vr-NZ-5Yj"/>
+                        <constraint firstItem="vJP-em-vzJ" firstAttribute="centerY" secondItem="ySm-Or-cry" secondAttribute="centerY" id="4to-6o-TIt"/>
+                        <constraint firstItem="Z2c-Y5-JPA" firstAttribute="centerY" secondItem="ySm-Or-cry" secondAttribute="centerY" id="7ab-Ws-Xuo"/>
+                        <constraint firstItem="mGl-dI-rCl" firstAttribute="trailing" secondItem="IbR-gO-EMr" secondAttribute="trailing" id="8Ta-sM-fmj"/>
+                        <constraint firstAttribute="trailing" secondItem="I8N-pM-mro" secondAttribute="trailing" constant="12" id="AGz-Fb-LnU"/>
+                        <constraint firstItem="Lq4-ga-A7R" firstAttribute="leading" secondItem="vJP-em-vzJ" secondAttribute="trailing" constant="10" id="AHW-HU-zhs"/>
+                        <constraint firstAttribute="height" constant="73" id="FGu-gU-ikC"/>
+                        <constraint firstItem="I8N-pM-mro" firstAttribute="leading" secondItem="Lq4-ga-A7R" secondAttribute="leading" id="FUA-xc-X82"/>
+                        <constraint firstItem="mGl-dI-rCl" firstAttribute="leading" secondItem="IbR-gO-EMr" secondAttribute="leading" id="FyH-Bg-WrU"/>
+                        <constraint firstItem="Lq4-ga-A7R" firstAttribute="top" secondItem="ySm-Or-cry" secondAttribute="top" constant="20" id="Mth-9R-s6K"/>
+                        <constraint firstItem="xB0-uR-3Vs" firstAttribute="leading" secondItem="IbR-gO-EMr" secondAttribute="leading" id="PGo-MX-r0D"/>
+                        <constraint firstItem="mGl-dI-rCl" firstAttribute="bottom" secondItem="IbR-gO-EMr" secondAttribute="bottom" id="UKV-dP-jb4"/>
+                        <constraint firstAttribute="trailing" secondItem="Lq4-ga-A7R" secondAttribute="trailing" constant="12" id="Wir-QO-mim"/>
+                        <constraint firstItem="I8N-pM-mro" firstAttribute="top" secondItem="Lq4-ga-A7R" secondAttribute="bottom" constant="4" id="XVM-Ko-OkK"/>
+                        <constraint firstItem="Z2c-Y5-JPA" firstAttribute="leading" secondItem="ySm-Or-cry" secondAttribute="leading" id="Xjv-we-kqb"/>
+                        <constraint firstItem="IbR-gO-EMr" firstAttribute="leading" secondItem="Z2c-Y5-JPA" secondAttribute="trailing" constant="12" id="cuD-f9-C1r"/>
+                        <constraint firstItem="mGl-dI-rCl" firstAttribute="top" secondItem="IbR-gO-EMr" secondAttribute="top" id="gfW-zB-wrB"/>
+                        <constraint firstItem="xB0-uR-3Vs" firstAttribute="trailing" secondItem="IbR-gO-EMr" secondAttribute="trailing" id="ikF-Uo-fWR"/>
+                        <constraint firstItem="xB0-uR-3Vs" firstAttribute="bottom" secondItem="IbR-gO-EMr" secondAttribute="bottom" id="qJA-gK-5iK"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="10"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0wJ-e7-ouI">
+                    <rect key="frame" x="86.666666666666686" y="190" width="220" height="38"/>
+                    <color key="backgroundColor" red="0.1764705882352941" green="0.7803921568627451" blue="0.66666666666666663" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="38" id="K9L-wd-aJd"/>
+                        <constraint firstAttribute="width" constant="220" id="WV4-5d-yoT"/>
+                    </constraints>
+                    <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                    <state key="normal" title="发布作品"/>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="19"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                    <connections>
+                        <action selector="sureAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="TwC-pw-oyY"/>
+                    </connections>
+                </button>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NpE-3V-eM1">
+                    <rect key="frame" x="12" y="0.0" width="369" height="87"/>
+                    <subviews>
+                        <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EYP-nq-h0J">
+                            <rect key="frame" x="12" y="0.0" width="345" height="87"/>
+                            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <color key="textColor" red="0.2666666667" green="0.2666666667" blue="0.2666666667" alpha="1" colorSpace="calibratedRGB"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <textInputTraits key="textInputTraits" autocapitalizationType="sentences" enablesReturnKeyAutomatically="YES"/>
+                        </textView>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="我发布了一首演奏作品,快来听听吧~" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="glk-go-0oW">
+                            <rect key="frame" x="12" y="10" width="243" height="17"/>
+                            <fontDescription key="fontDescription" type="system" pointSize="14"/>
+                            <color key="textColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0/150" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lro-Xx-AAz">
+                            <rect key="frame" x="325" y="58" width="32" height="20"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="20" id="83V-tz-Cpg"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" pointSize="12"/>
+                            <color key="textColor" red="0.66666666669999997" green="0.66666666669999997" blue="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                    </subviews>
+                    <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                    <constraints>
+                        <constraint firstItem="glk-go-0oW" firstAttribute="leading" secondItem="NpE-3V-eM1" secondAttribute="leading" constant="12" id="3kw-tz-XVV"/>
+                        <constraint firstItem="EYP-nq-h0J" firstAttribute="top" secondItem="NpE-3V-eM1" secondAttribute="top" id="GLb-KA-3Zz"/>
+                        <constraint firstAttribute="height" constant="87" id="MM1-lx-Cmu"/>
+                        <constraint firstAttribute="bottom" secondItem="lro-Xx-AAz" secondAttribute="bottom" constant="9" id="c5Y-ih-yEg"/>
+                        <constraint firstItem="EYP-nq-h0J" firstAttribute="leading" secondItem="NpE-3V-eM1" secondAttribute="leading" constant="12" id="erk-lD-qR7"/>
+                        <constraint firstItem="glk-go-0oW" firstAttribute="top" secondItem="NpE-3V-eM1" secondAttribute="top" constant="10" id="ncg-6K-1re"/>
+                        <constraint firstAttribute="trailing" secondItem="lro-Xx-AAz" secondAttribute="trailing" constant="12" id="sOe-Ih-nSR"/>
+                        <constraint firstAttribute="trailing" secondItem="EYP-nq-h0J" secondAttribute="trailing" constant="12" id="tXY-CK-lhd"/>
+                        <constraint firstAttribute="bottom" secondItem="EYP-nq-h0J" secondAttribute="bottom" id="vZM-tS-pb2"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="10"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstAttribute="bottom" secondItem="0wJ-e7-ouI" secondAttribute="bottom" constant="18" id="Ba7-0l-oGc"/>
+                <constraint firstAttribute="trailing" secondItem="NpE-3V-eM1" secondAttribute="trailing" constant="12" id="H3O-rj-Pdv"/>
+                <constraint firstAttribute="trailing" secondItem="ySm-Or-cry" secondAttribute="trailing" constant="12" id="Pqm-nZ-Nhi"/>
+                <constraint firstItem="0wJ-e7-ouI" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Qhu-ND-VFC"/>
+                <constraint firstItem="ySm-Or-cry" firstAttribute="top" secondItem="NpE-3V-eM1" secondAttribute="bottom" constant="12" id="RVK-fV-L77"/>
+                <constraint firstItem="NpE-3V-eM1" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="YZ5-PY-Ced"/>
+                <constraint firstItem="ySm-Or-cry" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="12" id="ev9-kC-cbD"/>
+                <constraint firstItem="NpE-3V-eM1" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="12" id="jir-QV-hWq"/>
+                <constraint firstItem="0wJ-e7-ouI" firstAttribute="top" secondItem="ySm-Or-cry" secondAttribute="bottom" constant="18" id="n6Y-mi-EJu"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="backView" destination="xB0-uR-3Vs" id="J3a-fb-kKX"/>
+                <outlet property="countLabel" destination="lro-Xx-AAz" id="hyn-Cm-7d9"/>
+                <outlet property="musicImage" destination="IbR-gO-EMr" id="GX0-pM-jOo"/>
+                <outlet property="musicName" destination="Lq4-ga-A7R" id="hLK-Cr-9Vv"/>
+                <outlet property="sureButton" destination="0wJ-e7-ouI" id="qo3-HE-Z5X"/>
+                <outlet property="textView" destination="EYP-nq-h0J" id="yCJ-fa-yQp"/>
+                <outlet property="tipsLabel" destination="glk-go-0oW" id="V2E-OK-68E"/>
+                <outlet property="userName" destination="I8N-pM-mro" id="zzf-Zy-vet"/>
+            </connections>
+            <point key="canvasLocation" x="58.778625954198468" y="-188.02816901408451"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="music_coverBg" width="54" height="54"/>
+        <image name="pub_music_placeholder" width="205" height="205"/>
+        <image name="unChoose_status" width="18" height="18"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 32 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublistAlert.h

@@ -0,0 +1,32 @@
+//
+//  MusicPublistAlert.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/1.
+//
+
+#import <UIKit/UIKit.h>
+#import "VideoCoverChooseView.h"
+#import "MusicPublicContentView.h"
+#import "MusicPubHeader.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface MusicPublistAlert : UIView
+
+@property (nonatomic, strong) VideoCoverChooseView *coverView;
+
+@property (nonatomic, strong) MusicPublicContentView *publishContainView;
+
++ (instancetype)shareInstance;
+
+- (void)configUI:(BOOL)isVideoPublish;
+
+- (void)evaluateMusicName:(NSString *)musicName userName:(NSString *)userName musicImage:(NSString *)musicImage;
+
+- (void)chooseAction:(MusicPublishCallback)callback;
+
+- (void)showAlert;
+@end
+
+NS_ASSUME_NONNULL_END

+ 138 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublistAlert.m

@@ -0,0 +1,138 @@
+//
+//  MusicPublistAlert.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/1.
+//
+
+#import "MusicPublistAlert.h"
+
+
+@interface MusicPublistAlert ()
+
+@property (nonatomic, strong) UIScrollView *scrollView;
+
+@property (weak, nonatomic) IBOutlet UIView *containerView;
+
+
+@property (nonatomic, copy) MusicPublishCallback callback;
+
+@end
+
+@implementation MusicPublistAlert
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    [self.containerView addSubview:self.scrollView];
+    [self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(self.containerView);
+    }];
+}
++ (instancetype)shareInstance {
+    MusicPublistAlert *view = [[[NSBundle mainBundle] loadNibNamed:@"MusicPublistAlert" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (void)configUI:(BOOL)isVideoPublish {
+    MJWeakSelf;
+    if (isVideoPublish) {
+        self.coverView = [VideoCoverChooseView shareInstance];
+        [self.coverView chooseImageCallback:^(PUBLISH_ACTION type) {
+            [weakSelf endEditing:YES];
+            if (weakSelf.callback) {
+                weakSelf.callback(type);
+            }
+        }];
+        [self.scrollView addSubview:self.coverView];
+        CGFloat coverHeigt = [VideoCoverChooseView getViewHeight];
+        [self.coverView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.containerView);
+            make.top.mas_equalTo(self.scrollView.mas_top);
+            make.height.mas_equalTo(coverHeigt);
+        }];
+        // container
+        self.publishContainView = [MusicPublicContentView shareInstance];
+        [self.scrollView addSubview:self.publishContainView];
+        CGFloat height = [MusicPublicContentView getViewHeight];
+        [self.publishContainView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.mas_equalTo(self.containerView);
+            make.top.mas_equalTo(self.coverView.mas_bottom);
+            make.bottom.mas_equalTo(self.scrollView.mas_bottom);
+            make.height.mas_equalTo(height);
+        }];
+        [self.publishContainView musicContentPubAction:^(PUBLISH_ACTION type) {
+            [weakSelf endEditing:YES];
+            if (type == PUBLISH_ACTION_PUBLISH) {
+                [weakSelf hideAlert];
+            }
+            if (weakSelf.callback) {
+                weakSelf.callback(type);
+            }
+        }];
+    }
+    else {
+        // container
+        self.publishContainView = [MusicPublicContentView shareInstance];
+        [self addSubview:self.publishContainView];
+        CGFloat height = [MusicPublicContentView getViewHeight];
+        [self.publishContainView mas_makeConstraints:^(MASConstraintMaker *make) {
+            make.left.right.top.bottom.mas_equalTo(self.containerView);
+        }];
+        [self.publishContainView musicContentPubAction:^(PUBLISH_ACTION type) {
+            [weakSelf endEditing:YES];
+            if (type == PUBLISH_ACTION_PUBLISH) {
+                [weakSelf hideAlert];
+            }
+            if (weakSelf.callback) {
+                weakSelf.callback(type);
+            }
+        }];
+    }
+}
+
+- (void)evaluateMusicName:(NSString *)musicName userName:(NSString *)userName musicImage:(NSString *)musicImage {
+    self.publishContainView.musicName.text = [NSString returnNoNullStringWithString:musicName];
+    [self.publishContainView.musicImage sd_setImageWithURL:[NSURL URLWithString:[musicImage getUrlEndcodeString]] placeholderImage:[UIImage imageNamed:@"music_placeholder"]];
+    self.publishContainView.userName.text = [NSString returnNoNullStringWithString:userName];
+}
+
+- (void)chooseAction:(MusicPublishCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+
+- (IBAction)cancleAction:(id)sender {
+    [self hideAlert];
+}
+
+- (void)showAlert {
+    UIWindow *window = [NSObject getKeyWindow];
+    [window addSubview:self];
+    [self mas_makeConstraints:^(MASConstraintMaker *make) {
+        make.left.right.top.bottom.mas_equalTo(window);
+    }];
+}
+
+- (void)hideAlert {
+    [self removeFromSuperview];
+}
+
+- (UIScrollView *)scrollView {
+    if (!_scrollView) {
+        _scrollView = [[UIScrollView alloc] init];
+        _scrollView.showsVerticalScrollIndicator = NO;
+        _scrollView.showsHorizontalScrollIndicator = NO;
+        _scrollView.bounces = NO;
+    }
+    return _scrollView;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 90 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/MusicPublistAlert.xib

@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="MusicPublistAlert">
+            <rect key="frame" x="0.0" y="0.0" width="687" height="520"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="crp-Dg-bEh">
+                    <rect key="frame" x="185.66666666666663" y="104.66666666666669" width="316" height="311"/>
+                    <subviews>
+                        <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="作品详情" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="te4-O1-RAs">
+                            <rect key="frame" x="125.33333333333334" y="15" width="65.333333333333343" height="22"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="22" id="9P9-gf-TQs"/>
+                            </constraints>
+                            <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
+                            <color key="textColor" red="0.074509803921568626" green="0.078431372549019607" blue="0.082352941176470587" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                            <nil key="highlightedColor"/>
+                        </label>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="VSu-Ld-Rbu">
+                            <rect key="frame" x="0.0" y="56" width="316" height="255"/>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        </view>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cancle_button" translatesAutoresizingMaskIntoConstraints="NO" id="uSL-RT-oX5">
+                            <rect key="frame" x="287" y="11" width="19" height="19"/>
+                            <constraints>
+                                <constraint firstAttribute="width" constant="19" id="LRY-32-rBI"/>
+                                <constraint firstAttribute="height" constant="19" id="dWq-Go-3Vb"/>
+                            </constraints>
+                        </imageView>
+                        <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8mM-Qw-PGH">
+                            <rect key="frame" x="276" y="0.0" width="40" height="40"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="40" id="SR0-Xr-LNe"/>
+                                <constraint firstAttribute="width" constant="40" id="zIs-lk-2mh"/>
+                            </constraints>
+                            <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                            <connections>
+                                <action selector="cancleAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="7JR-cS-Y5p"/>
+                            </connections>
+                        </button>
+                    </subviews>
+                    <color key="backgroundColor" red="0.97254901960784312" green="0.97254901960784312" blue="0.97254901960784312" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="311" id="3bE-RT-gdX"/>
+                        <constraint firstAttribute="width" constant="316" id="5Vp-Nm-Phf"/>
+                        <constraint firstItem="VSu-Ld-Rbu" firstAttribute="leading" secondItem="crp-Dg-bEh" secondAttribute="leading" id="Ar8-21-yBw"/>
+                        <constraint firstAttribute="trailing" secondItem="uSL-RT-oX5" secondAttribute="trailing" constant="10" id="JvH-Ld-uxt"/>
+                        <constraint firstItem="8mM-Qw-PGH" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" id="P4Y-hH-uUz"/>
+                        <constraint firstAttribute="bottom" secondItem="VSu-Ld-Rbu" secondAttribute="bottom" id="Qul-Iw-vdi"/>
+                        <constraint firstItem="te4-O1-RAs" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" constant="15" id="ci5-BA-awW"/>
+                        <constraint firstAttribute="trailing" secondItem="8mM-Qw-PGH" secondAttribute="trailing" id="ehJ-JA-HqW"/>
+                        <constraint firstItem="VSu-Ld-Rbu" firstAttribute="top" secondItem="te4-O1-RAs" secondAttribute="bottom" constant="19" id="ncm-iM-Is7"/>
+                        <constraint firstItem="uSL-RT-oX5" firstAttribute="top" secondItem="crp-Dg-bEh" secondAttribute="top" constant="11" id="nwL-G4-dhm"/>
+                        <constraint firstItem="te4-O1-RAs" firstAttribute="centerX" secondItem="crp-Dg-bEh" secondAttribute="centerX" id="xB7-AF-HP0"/>
+                        <constraint firstAttribute="trailing" secondItem="VSu-Ld-Rbu" secondAttribute="trailing" id="z0h-ml-YDQ"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="12"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+            </subviews>
+            <color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
+            <constraints>
+                <constraint firstItem="crp-Dg-bEh" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Q7S-rU-daX"/>
+                <constraint firstItem="crp-Dg-bEh" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="l1H-ZN-yAQ"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="containerView" destination="VSu-Ld-Rbu" id="IVZ-aq-krM"/>
+            </connections>
+            <point key="canvasLocation" x="121.37404580152672" y="-23.239436619718312"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="cancle_button" width="20" height="20"/>
+    </resources>
+</document>

+ 27 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCoverChooseView.h

@@ -0,0 +1,27 @@
+//
+//  VideoCoverChooseView.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import <UIKit/UIKit.h>
+#import "MusicPubHeader.h"
+
+typedef void(^VideoCoverChooseCallback)(PUBLISH_ACTION type);
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface VideoCoverChooseView : UIView
+
+@property (weak, nonatomic) IBOutlet UIImageView *coverImage;
+
++ (instancetype)shareInstance;
+
+- (void)chooseImageCallback:(VideoCoverChooseCallback)callback;
+
++ (CGFloat)getViewHeight;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 59 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCoverChooseView.m

@@ -0,0 +1,59 @@
+//
+//  VideoCoverChooseView.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "VideoCoverChooseView.h"
+#import "UIView+KSLayer.h"
+
+@interface VideoCoverChooseView ()
+@property (weak, nonatomic) IBOutlet UIView *layerView;
+
+@property (nonatomic, copy) VideoCoverChooseCallback callback;
+
+@end
+
+@implementation VideoCoverChooseView
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    CAGradientLayer *viewLayer = [UIView createGradientLayerFromColor:HexRGB(0x80B1C8) startPoint:CGPointMake(0, 0.5) endColor:HexRGB(0x3A98A2) endPoint:CGPointMake(0.5, 1) bounds:CGRectMake(0, 0, 248, 30)];
+    [self.layerView.layer addSublayer:viewLayer];
+}
++ (instancetype)shareInstance {
+    VideoCoverChooseView *view = [[[NSBundle mainBundle] loadNibNamed:@"VideoCoverChooseView" owner:nil options:nil] firstObject];
+    return view;
+}
+
+- (IBAction)albumChoose:(id)sender {
+    if (self.callback) {
+        self.callback(PUBLISH_ACTION_VIDEOCOVER);
+    }
+}
+
+- (IBAction)videoCrop:(id)sender {
+    if (self.callback) {
+        self.callback(PUBLISH_ACTION_VIDEOCROP);
+    }
+}
+
+- (void)chooseImageCallback:(VideoCoverChooseCallback)callback {
+    if (callback) {
+        self.callback = callback;
+    }
+}
+
+
++ (CGFloat)getViewHeight {
+    return 163.0f;
+}
+/*
+// Only override drawRect: if you perform custom drawing.
+// An empty implementation adversely affects performance during animation.
+- (void)drawRect:(CGRect)rect {
+    // Drawing code
+}
+*/
+
+@end

+ 177 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCoverChooseView.xib

@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="System colors in document resources" minToolsVersion="11.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="VideoCoverChooseView">
+            <rect key="frame" x="0.0" y="0.0" width="316" height="163"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <subviews>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Rod-ju-kqd">
+                    <rect key="frame" x="13" y="0.0" width="290" height="136"/>
+                    <subviews>
+                        <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="videoMerge_cover" translatesAutoresizingMaskIntoConstraints="NO" id="Yfw-f3-ca2">
+                            <rect key="frame" x="0.0" y="0.0" width="290" height="136"/>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="10"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </imageView>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="trailing" secondItem="Yfw-f3-ca2" secondAttribute="trailing" id="2ZX-mF-kFV"/>
+                        <constraint firstAttribute="height" constant="136" id="C6o-HO-W1z"/>
+                        <constraint firstAttribute="bottom" secondItem="Yfw-f3-ca2" secondAttribute="bottom" id="GsL-sh-WZO"/>
+                        <constraint firstItem="Yfw-f3-ca2" firstAttribute="leading" secondItem="Rod-ju-kqd" secondAttribute="leading" id="I70-AY-OHA"/>
+                        <constraint firstItem="Yfw-f3-ca2" firstAttribute="top" secondItem="Rod-ju-kqd" secondAttribute="top" id="WVR-yM-gfe"/>
+                    </constraints>
+                </view>
+                <view alpha="0.58999999999999997" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Eoj-tF-ifL">
+                    <rect key="frame" x="34" y="121" width="248" height="30"/>
+                    <color key="backgroundColor" red="0.50196078431372548" green="0.61960784313725492" blue="0.78431372549019607" alpha="1" colorSpace="calibratedRGB"/>
+                    <constraints>
+                        <constraint firstAttribute="height" constant="30" id="7rL-iS-MKS"/>
+                        <constraint firstAttribute="width" constant="248" id="hHH-4o-745"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="15"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="TOX-dY-1lt">
+                    <rect key="frame" x="34" y="121" width="248" height="30"/>
+                    <subviews>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="sPz-fl-Upn">
+                            <rect key="frame" x="0.0" y="0.0" width="123" height="30"/>
+                            <subviews>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cover_choose_image" translatesAutoresizingMaskIntoConstraints="NO" id="b49-x9-Ry1">
+                                    <rect key="frame" x="15" y="7" width="16" height="16"/>
+                                    <constraints>
+                                        <constraint firstAttribute="width" constant="16" id="KTD-Sz-fLl"/>
+                                        <constraint firstAttribute="height" constant="16" id="tg3-wE-3tv"/>
+                                    </constraints>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="相册获取封面" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="wD9-9N-1Ea">
+                                    <rect key="frame" x="35" y="7.6666666666666572" width="74" height="15"/>
+                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
+                                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="rgT-xS-ewk">
+                                    <rect key="frame" x="0.0" y="0.0" width="123" height="30"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="albumChoose:" destination="iN0-l3-epB" eventType="touchUpInside" id="85f-AQ-i0Q"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstAttribute="bottom" secondItem="rgT-xS-ewk" secondAttribute="bottom" id="4ak-Zl-K0d"/>
+                                <constraint firstItem="wD9-9N-1Ea" firstAttribute="centerY" secondItem="sPz-fl-Upn" secondAttribute="centerY" id="MEU-Gc-U7P"/>
+                                <constraint firstItem="b49-x9-Ry1" firstAttribute="centerY" secondItem="sPz-fl-Upn" secondAttribute="centerY" id="O6C-6S-zD8"/>
+                                <constraint firstItem="rgT-xS-ewk" firstAttribute="top" secondItem="sPz-fl-Upn" secondAttribute="top" id="Oxs-x8-aFB"/>
+                                <constraint firstAttribute="trailing" secondItem="rgT-xS-ewk" secondAttribute="trailing" id="doi-yT-5Ol"/>
+                                <constraint firstItem="wD9-9N-1Ea" firstAttribute="leading" secondItem="b49-x9-Ry1" secondAttribute="trailing" constant="4" id="flu-1E-HCY"/>
+                                <constraint firstItem="b49-x9-Ry1" firstAttribute="centerY" secondItem="sPz-fl-Upn" secondAttribute="centerY" id="gVa-dp-wvO"/>
+                                <constraint firstItem="rgT-xS-ewk" firstAttribute="leading" secondItem="sPz-fl-Upn" secondAttribute="leading" id="lAt-dR-qYW"/>
+                                <constraint firstItem="b49-x9-Ry1" firstAttribute="leading" secondItem="sPz-fl-Upn" secondAttribute="leading" constant="15" id="leT-o0-A0I"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="s7h-QL-lWX">
+                            <rect key="frame" x="125" y="0.0" width="123" height="30"/>
+                            <subviews>
+                                <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="cover_crop_image" translatesAutoresizingMaskIntoConstraints="NO" id="uBM-vB-63W">
+                                    <rect key="frame" x="16" y="7" width="16" height="16"/>
+                                </imageView>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="视频截取封面" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oaL-43-caz">
+                                    <rect key="frame" x="36.000000000000007" y="7.6666666666666572" width="73.666666666666686" height="15"/>
+                                    <fontDescription key="fontDescription" type="system" weight="medium" pointSize="12"/>
+                                    <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
+                                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="SaH-IM-rMB">
+                                    <rect key="frame" x="0.0" y="0.0" width="123" height="30"/>
+                                    <inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
+                                    <connections>
+                                        <action selector="videoCrop:" destination="iN0-l3-epB" eventType="touchUpInside" id="5FD-qB-TSL"/>
+                                    </connections>
+                                </button>
+                            </subviews>
+                            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstItem="SaH-IM-rMB" firstAttribute="leading" secondItem="s7h-QL-lWX" secondAttribute="leading" id="3Zh-Gm-rbl"/>
+                                <constraint firstItem="uBM-vB-63W" firstAttribute="leading" secondItem="s7h-QL-lWX" secondAttribute="leading" constant="16" id="Z5H-P0-WjL"/>
+                                <constraint firstItem="uBM-vB-63W" firstAttribute="centerY" secondItem="s7h-QL-lWX" secondAttribute="centerY" id="Zhw-8g-7Se"/>
+                                <constraint firstItem="oaL-43-caz" firstAttribute="leading" secondItem="uBM-vB-63W" secondAttribute="trailing" constant="4" id="cvs-aQ-AEq"/>
+                                <constraint firstItem="oaL-43-caz" firstAttribute="centerY" secondItem="s7h-QL-lWX" secondAttribute="centerY" id="lbV-BV-pMY"/>
+                                <constraint firstAttribute="bottom" secondItem="SaH-IM-rMB" secondAttribute="bottom" id="sFE-dh-XyI"/>
+                                <constraint firstAttribute="trailing" secondItem="SaH-IM-rMB" secondAttribute="trailing" id="wew-aj-C4r"/>
+                                <constraint firstItem="SaH-IM-rMB" firstAttribute="top" secondItem="s7h-QL-lWX" secondAttribute="top" id="wks-xS-Aep"/>
+                            </constraints>
+                        </view>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="7Wb-ep-CKI">
+                            <rect key="frame" x="123" y="9.6666666666666572" width="2" height="11"/>
+                            <color key="backgroundColor" systemColor="systemBackgroundColor"/>
+                            <constraints>
+                                <constraint firstAttribute="height" constant="11" id="5Hu-Ha-fsy"/>
+                                <constraint firstAttribute="width" constant="2" id="AVF-5K-GM6"/>
+                            </constraints>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstItem="s7h-QL-lWX" firstAttribute="leading" secondItem="7Wb-ep-CKI" secondAttribute="trailing" id="JBb-gc-R0a"/>
+                        <constraint firstItem="sPz-fl-Upn" firstAttribute="top" secondItem="TOX-dY-1lt" secondAttribute="top" id="Kzt-5A-QL4"/>
+                        <constraint firstItem="7Wb-ep-CKI" firstAttribute="leading" secondItem="sPz-fl-Upn" secondAttribute="trailing" id="LtK-QD-0HD"/>
+                        <constraint firstAttribute="trailing" secondItem="s7h-QL-lWX" secondAttribute="trailing" id="QaQ-NL-SBU"/>
+                        <constraint firstAttribute="bottom" secondItem="sPz-fl-Upn" secondAttribute="bottom" id="Wou-Go-wuB"/>
+                        <constraint firstItem="s7h-QL-lWX" firstAttribute="top" secondItem="TOX-dY-1lt" secondAttribute="top" id="hIs-Yy-9oC"/>
+                        <constraint firstAttribute="bottom" secondItem="s7h-QL-lWX" secondAttribute="bottom" id="jKS-O5-yhv"/>
+                        <constraint firstItem="7Wb-ep-CKI" firstAttribute="centerX" secondItem="TOX-dY-1lt" secondAttribute="centerX" id="kAH-ni-mQa"/>
+                        <constraint firstItem="sPz-fl-Upn" firstAttribute="leading" secondItem="TOX-dY-1lt" secondAttribute="leading" id="smL-ff-bFt"/>
+                        <constraint firstItem="7Wb-ep-CKI" firstAttribute="centerY" secondItem="TOX-dY-1lt" secondAttribute="centerY" id="zZR-0Y-xHY"/>
+                    </constraints>
+                </view>
+            </subviews>
+            <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+            <constraints>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="trailing" secondItem="TOX-dY-1lt" secondAttribute="trailing" id="0LO-uR-sgt"/>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="bottom" secondItem="TOX-dY-1lt" secondAttribute="bottom" id="1sv-yO-kGe"/>
+                <constraint firstItem="Rod-ju-kqd" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="13" id="J0h-Tv-qF6"/>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="U1o-fC-wzj"/>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="leading" secondItem="TOX-dY-1lt" secondAttribute="leading" id="aJA-3E-8js"/>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="top" secondItem="TOX-dY-1lt" secondAttribute="top" id="aVH-Me-QLU"/>
+                <constraint firstItem="Rod-ju-kqd" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="plL-e8-8KF"/>
+                <constraint firstAttribute="trailing" secondItem="Rod-ju-kqd" secondAttribute="trailing" constant="13" id="rTU-2d-xDG"/>
+                <constraint firstItem="Eoj-tF-ifL" firstAttribute="centerY" secondItem="Rod-ju-kqd" secondAttribute="bottom" id="uG3-w7-Tgg"/>
+            </constraints>
+            <nil key="simulatedTopBarMetrics"/>
+            <nil key="simulatedBottomBarMetrics"/>
+            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
+            <connections>
+                <outlet property="coverImage" destination="Yfw-f3-ca2" id="Ejy-W6-GpP"/>
+                <outlet property="layerView" destination="Eoj-tF-ifL" id="qsd-FK-3bg"/>
+            </connections>
+            <point key="canvasLocation" x="58.015267175572518" y="-171.83098591549296"/>
+        </view>
+    </objects>
+    <resources>
+        <image name="cover_choose_image" width="16" height="16"/>
+        <image name="cover_crop_image" width="16" height="16"/>
+        <image name="videoMerge_cover" width="291" height="136"/>
+        <systemColor name="systemBackgroundColor">
+            <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+        </systemColor>
+    </resources>
+</document>

+ 18 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCropImageViewCell.h

@@ -0,0 +1,18 @@
+//
+//  VideoCropImageViewCell.h
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import <UIKit/UIKit.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface VideoCropImageViewCell : UICollectionViewCell
+
+- (void)configWithSource:(UIImage *)image;
+
+@end
+
+NS_ASSUME_NONNULL_END

+ 28 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCropImageViewCell.m

@@ -0,0 +1,28 @@
+//
+//  VideoCropImageViewCell.m
+//  KulexiuSchoolStudent
+//
+//  Created by 王智 on 2023/11/8.
+//
+
+#import "VideoCropImageViewCell.h"
+
+@interface VideoCropImageViewCell ()
+
+@property (weak, nonatomic) IBOutlet UIImageView *displayImage;
+
+
+@end
+
+@implementation VideoCropImageViewCell
+
+- (void)awakeFromNib {
+    [super awakeFromNib];
+    // Initialization code
+}
+
+- (void)configWithSource:(UIImage *)image {
+    [self.displayImage setImage:image];
+}
+
+@end

+ 39 - 0
KulexiuForTeacher/KulexiuForTeacher/Module/Mine/Works/View/VideoCropImageViewCell.xib

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
+    <device id="retina6_12" orientation="portrait" appearance="light"/>
+    <dependencies>
+        <deployment identifier="iOS"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
+        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
+        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
+    </dependencies>
+    <objects>
+        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
+        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
+        <collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="gTV-IL-0wX" customClass="VideoCropImageViewCell">
+            <rect key="frame" x="0.0" y="0.0" width="160" height="84"/>
+            <autoresizingMask key="autoresizingMask"/>
+            <view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
+                <rect key="frame" x="0.0" y="0.0" width="160" height="84"/>
+                <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                <subviews>
+                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="88X-kj-09O">
+                        <rect key="frame" x="0.0" y="0.0" width="160" height="84"/>
+                    </imageView>
+                </subviews>
+            </view>
+            <viewLayoutGuide key="safeArea" id="SEy-5g-ep8"/>
+            <constraints>
+                <constraint firstAttribute="trailing" secondItem="88X-kj-09O" secondAttribute="trailing" id="6XL-qL-qhv"/>
+                <constraint firstItem="88X-kj-09O" firstAttribute="leading" secondItem="gTV-IL-0wX" secondAttribute="leading" id="PIL-Pu-U0P"/>
+                <constraint firstAttribute="bottom" secondItem="88X-kj-09O" secondAttribute="bottom" id="m2v-qv-cKE"/>
+                <constraint firstItem="88X-kj-09O" firstAttribute="top" secondItem="gTV-IL-0wX" secondAttribute="top" id="pI2-be-0rE"/>
+            </constraints>
+            <size key="customSize" width="160" height="84"/>
+            <connections>
+                <outlet property="displayImage" destination="88X-kj-09O" id="Xbc-hG-WBX"/>
+            </connections>
+            <point key="canvasLocation" x="296.18320610687022" y="-2.1126760563380285"/>
+        </collectionViewCell>
+    </objects>
+</document>