Steven 2 anni fa
parent
commit
10b7b39ae4
18 ha cambiato i file con 325 aggiunte e 47 eliminazioni
  1. 13 9
      KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj
  2. 74 7
      KulexiuForStudent/KulexiuForStudent/Common/Base/AccompanyLoadingView.m
  3. 43 4
      KulexiuForStudent/KulexiuForStudent/Common/Base/AccompanyLoadingView.xib
  4. 90 2
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSAccompanyWebViewController.m
  5. 6 2
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSBaseWKWebViewController.m
  6. 1 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSLocalWebViewController.m
  7. 30 7
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSUploadManager.m
  8. 3 0
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSVideoRecordManager.h
  9. 10 7
      KulexiuForStudent/KulexiuForStudent/Common/Base/KSVideoRecordManager.m
  10. BIN
      KulexiuForStudent/KulexiuForStudent/Common/Base/banzou.mp3
  11. 3 0
      KulexiuForStudent/KulexiuForStudent/Common/Tools/Extension/NSDate+Extension.h
  12. 10 0
      KulexiuForStudent/KulexiuForStudent/Common/Tools/Extension/NSDate+Extension.m
  13. 2 0
      KulexiuForStudent/KulexiuForStudent/Common/Tools/VideoEditor/KSVideoEditor.h
  14. 33 3
      KulexiuForStudent/KulexiuForStudent/Common/Tools/VideoEditor/KSVideoEditor.m
  15. 1 0
      KulexiuForStudent/KulexiuForStudent/Module/Home/View/HotMusic/HomeHotMusicCellView.m
  16. 3 3
      KulexiuForStudent/KulexiuForStudent/Module/SealClass/Services/RTC/RTCService.m
  17. 1 1
      KulexiuForStudent/KulexiuForStudent/Module/Widget/Controller/ToneTuningViewController.m
  18. 2 2
      KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/TunerSettingView.xib

+ 13 - 9
KulexiuForStudent/KulexiuForStudent.xcodeproj/project.pbxproj

@@ -901,6 +901,7 @@
 		BCDE35882897B40000A9A560 /* shareImage@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = BCDE35872897B40000A9A560 /* shareImage@2x.png */; };
 		BCDE358E289A7D8700A9A560 /* KSGroupTagImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = BCDE358D289A7D8700A9A560 /* KSGroupTagImageView.m */; };
 		BCEBB8E82840B87100A76BE8 /* KSLiveChatroomMemberUp.m in Sources */ = {isa = PBXBuildFile; fileRef = BCEBB8E72840B87100A76BE8 /* KSLiveChatroomMemberUp.m */; };
+		BCED1596293D941200266AEB /* banzou.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = BCED1595293D941100266AEB /* banzou.mp3 */; };
 		BCED5CA7284F55A0009A42DE /* FriendListModel.m in Sources */ = {isa = PBXBuildFile; fileRef = BCED5CA6284F55A0009A42DE /* FriendListModel.m */; };
 		BCFCE44E28DD5C000051FED8 /* Low.wav in Resources */ = {isa = PBXBuildFile; fileRef = BCFCE44C28DD5C000051FED8 /* Low.wav */; };
 		BCFCE44F28DD5C000051FED8 /* High.wav in Resources */ = {isa = PBXBuildFile; fileRef = BCFCE44D28DD5C000051FED8 /* High.wav */; };
@@ -2522,6 +2523,7 @@
 		BCDE358D289A7D8700A9A560 /* KSGroupTagImageView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSGroupTagImageView.m; sourceTree = "<group>"; };
 		BCEBB8E62840B87100A76BE8 /* KSLiveChatroomMemberUp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KSLiveChatroomMemberUp.h; sourceTree = "<group>"; };
 		BCEBB8E72840B87100A76BE8 /* KSLiveChatroomMemberUp.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KSLiveChatroomMemberUp.m; sourceTree = "<group>"; };
+		BCED1595293D941100266AEB /* banzou.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = banzou.mp3; sourceTree = "<group>"; };
 		BCED5CA5284F55A0009A42DE /* FriendListModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FriendListModel.h; sourceTree = "<group>"; };
 		BCED5CA6284F55A0009A42DE /* FriendListModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FriendListModel.m; sourceTree = "<group>"; };
 		BCFCE44C28DD5C000051FED8 /* Low.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = Low.wav; sourceTree = "<group>"; };
@@ -4056,6 +4058,7 @@
 		2779350B27E324A40010E277 /* Base */ = {
 			isa = PBXGroup;
 			children = (
+				BCED1595293D941100266AEB /* banzou.mp3 */,
 				BCC5839328A9EC5C00BAB4CF /* CloudLoadingSource */,
 				BC8EC02428926B2C00D51094 /* CustomLoading */,
 				BC71D27C288807400010F14B /* TabbarAnimation */,
@@ -5317,15 +5320,15 @@
 			isa = PBXGroup;
 			children = (
 				BC8C2C4C2823F57100FBA5D5 /* AddressBottomView.h */,
+				BC8C2C532823F57100FBA5D5 /* AddressBottomView.m */,
 				BC8C2C4D2823F57100FBA5D5 /* AddressBottomView.xib */,
-				BC8C2C4E2823F57100FBA5D5 /* MyAddressListCell.h */,
-				BC8C2C4F2823F57100FBA5D5 /* KSAddressPickerView.m */,
+				BC8C2C542823F57100FBA5D5 /* AddressDetailBodyView.h */,
 				BC8C2C502823F57100FBA5D5 /* AddressDetailBodyView.m */,
 				BC8C2C512823F57100FBA5D5 /* AddressDetailBodyView.xib */,
-				BC8C2C522823F57100FBA5D5 /* MyAddressListCell.m */,
-				BC8C2C532823F57100FBA5D5 /* AddressBottomView.m */,
-				BC8C2C542823F57100FBA5D5 /* AddressDetailBodyView.h */,
 				BC8C2C552823F57100FBA5D5 /* KSAddressPickerView.h */,
+				BC8C2C4F2823F57100FBA5D5 /* KSAddressPickerView.m */,
+				BC8C2C4E2823F57100FBA5D5 /* MyAddressListCell.h */,
+				BC8C2C522823F57100FBA5D5 /* MyAddressListCell.m */,
 				BC8C2C562823F57100FBA5D5 /* MyAddressListCell.xib */,
 			);
 			path = View;
@@ -6567,6 +6570,7 @@
 				27F9032D27E87C2E00C08A19 /* KSNetworkAlert.xib in Resources */,
 				BC71D260288804CD0010F14B /* img_44.png in Resources */,
 				BC71D26C288804CD0010F14B /* img_9.png in Resources */,
+				BCED1596293D941200266AEB /* banzou.mp3 in Resources */,
 				BC736A93288036E8004A9B0A /* MyVideoSearchView.xib in Resources */,
 				BCC583C528A9EC6400BAB4CF /* cloud_animation_17.png in Resources */,
 				BCC583CE28A9EC6400BAB4CF /* cloud_animation_0.png in Resources */,
@@ -7687,7 +7691,7 @@
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_ENTITLEMENTS = KulexiuForStudent/KulexiuForStudent.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 1.4.3;
+				CURRENT_PROJECT_VERSION = 1.4.4;
 				DEVELOPMENT_TEAM = B2AP53HHTU;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -7743,7 +7747,7 @@
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/SocialLibraries/Sina/SinaSDK",
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/UMSocialSDKPlugin",
 				);
-				MARKETING_VERSION = 1.4.3;
+				MARKETING_VERSION = 1.4.4;
 				PRODUCT_BUNDLE_IDENTIFIER = com.Colexiu.KulexiuForStudent;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_EMIT_LOC_STRINGS = YES;
@@ -7764,7 +7768,7 @@
 				CLANG_ENABLE_MODULES = YES;
 				CODE_SIGN_ENTITLEMENTS = KulexiuForStudent/KulexiuForStudent.entitlements;
 				CODE_SIGN_STYLE = Automatic;
-				CURRENT_PROJECT_VERSION = 1.4.3;
+				CURRENT_PROJECT_VERSION = 1.4.4;
 				DEVELOPMENT_TEAM = B2AP53HHTU;
 				ENABLE_BITCODE = NO;
 				FRAMEWORK_SEARCH_PATHS = (
@@ -7820,7 +7824,7 @@
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/SocialLibraries/Sina/SinaSDK",
 					"$(PROJECT_DIR)/KulexiuForStudent/Common/ThirdPart/UMSocialSDK/share/share_ios_6.10.5/UMSocialSDKPlugin",
 				);
-				MARKETING_VERSION = 1.4.3;
+				MARKETING_VERSION = 1.4.4;
 				PRODUCT_BUNDLE_IDENTIFIER = com.Colexiu.KulexiuForStudent;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_EMIT_LOC_STRINGS = YES;

+ 74 - 7
KulexiuForStudent/KulexiuForStudent/Common/Base/AccompanyLoadingView.m

@@ -10,6 +10,13 @@
 
 
 @interface AccompanyLoadingView ()
+{
+    NSTimer *_timer;
+    NSInteger _timeCount;
+    CGFloat _count;
+}
+
+@property (weak, nonatomic) IBOutlet NSLayoutConstraint *loadWidth;
 
 @property (weak, nonatomic) IBOutlet UIView *loadContainer;
 
@@ -41,6 +48,10 @@
 }
 
 - (void)showLoading {
+    
+    self.layer.opacity = 1.0f;
+    [self resetTimeCount];
+    [self startTimer];
     if (self.animationView.isAnimationPlaying) {
         return;
     }
@@ -50,22 +61,28 @@
             make.left.right.top.bottom.mas_equalTo(self.loadContainer);
         }];
     }
-    self.layer.opacity = 1.0f;
     [self.animationView play];
 }
 
 - (void)stopLoading {
-    if (self.animationView.isAnimationPlaying) {
-        [self.animationView stop];
-    }
-    [UIView animateWithDuration:1.0f animations:^{
-        self.layer.opacity = 0.0f;
+    [UIView animateWithDuration:0.3 animations:^{
+        self.loadWidth.constant = 300.0f;
     } completion:^(BOOL finished) {
-        [self removeFromSuperview];
+        [self stopTimer];
+        if (self.animationView.isAnimationPlaying) {
+            [self.animationView stop];
+        }
+        [UIView animateWithDuration:1.0f animations:^{
+            self.layer.opacity = 0.0f;
+        } completion:^(BOOL finished) {
+            [self resetTimeCount];
+            [self removeFromSuperview];
+        }];
     }];
 }
 
 - (IBAction)cancleAction:(id)sender {
+    [self stopTimer];
     if (self.animationView.isAnimationPlaying) {
         [self.animationView stop];
     }
@@ -83,6 +100,56 @@
     }
     return _animationView;
 }
+
+- (void)resetTimeCount {
+    _timeCount = 0;
+    _count = 0;
+    self.loadWidth.constant = 0.0f;
+}
+
+- (void)startTimer {
+    _timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(loadingAction) userInfo:nil repeats:YES];
+    [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
+}
+
+- (void)stopTimer {
+    if (_timer) {
+        [_timer invalidate];
+        _timer = nil;
+    }
+}
+
+- (void)loadingAction {
+    _timeCount++;
+    if (_count >= 99.9) {
+        return;
+    }
+    if (_timeCount <= 10) {
+        _count +=5;
+    }
+    else if (10 < _timeCount && _timeCount <= 30) {
+        _count = _count + 2;
+    }
+    else if ( 30 < _timeCount && _timeCount <= 60) {
+        _count = _count + 0.3;
+    }
+    else if (60 < _timeCount && _timeCount <= 120) {
+        _count = _count + 0.01;
+    }
+    else {
+        _count = _count + 0.002;
+    }
+    [UIView animateWithDuration:0.1f animations:^{
+        self.loadWidth.constant = 300.0f * self->_count / 100;
+    }];
+}
+
+- (void)dealloc {
+    if (_timer) {
+        [_timer invalidate];
+        _timer = nil;
+    }
+}
 /*
 // Only override drawRect: if you perform custom drawing.
 // An empty implementation adversely affects performance during animation.

+ 43 - 4
KulexiuForStudent/KulexiuForStudent/Common/Base/AccompanyLoadingView.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="21225" 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="21207"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     <objects>
@@ -25,7 +25,7 @@
                     </constraints>
                 </view>
                 <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="小酷正在努力加载,请稍等..." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Bjn-zM-LJW">
-                    <rect key="frame" x="258" y="293" width="183.5" height="17"/>
+                    <rect key="frame" x="258" y="271" width="183.5" height="17"/>
                     <fontDescription key="fontDescription" type="system" pointSize="14"/>
                     <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
                     <nil key="highlightedColor"/>
@@ -48,14 +48,51 @@
                         <action selector="cancleAction:" destination="iN0-l3-epB" eventType="touchUpInside" id="dvV-tf-Ggg"/>
                     </connections>
                 </button>
+                <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5FN-Gd-tjU">
+                    <rect key="frame" x="199.5" y="308" width="300" height="12"/>
+                    <subviews>
+                        <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1OP-rv-oYu">
+                            <rect key="frame" x="0.0" y="0.0" width="0.0" height="12"/>
+                            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                            <constraints>
+                                <constraint firstAttribute="width" id="kYR-E7-B2J"/>
+                            </constraints>
+                            <userDefinedRuntimeAttributes>
+                                <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                    <real key="value" value="6"/>
+                                </userDefinedRuntimeAttribute>
+                            </userDefinedRuntimeAttributes>
+                        </view>
+                    </subviews>
+                    <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                    <constraints>
+                        <constraint firstAttribute="width" constant="300" id="CqR-Gh-p9l"/>
+                        <constraint firstAttribute="height" constant="12" id="YaA-Um-8Nh"/>
+                        <constraint firstItem="1OP-rv-oYu" firstAttribute="leading" secondItem="5FN-Gd-tjU" secondAttribute="leading" id="kqM-2d-QSN"/>
+                        <constraint firstItem="1OP-rv-oYu" firstAttribute="top" secondItem="5FN-Gd-tjU" secondAttribute="top" id="lkc-Rn-U9k"/>
+                        <constraint firstAttribute="bottom" secondItem="1OP-rv-oYu" secondAttribute="bottom" id="ruV-0W-bwY"/>
+                    </constraints>
+                    <userDefinedRuntimeAttributes>
+                        <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                            <real key="value" value="6"/>
+                        </userDefinedRuntimeAttribute>
+                        <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                            <color key="value" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
+                        </userDefinedRuntimeAttribute>
+                        <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                            <real key="value" value="1"/>
+                        </userDefinedRuntimeAttribute>
+                    </userDefinedRuntimeAttributes>
+                </view>
             </subviews>
             <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
             <constraints>
+                <constraint firstAttribute="bottom" secondItem="5FN-Gd-tjU" secondAttribute="bottom" constant="20" id="2eU-L3-gpy"/>
                 <constraint firstItem="ZV3-qJ-uxE" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="3r2-vl-mBg"/>
                 <constraint firstAttribute="trailing" secondItem="ZV3-qJ-uxE" secondAttribute="trailing" id="QY7-u1-n6M"/>
                 <constraint firstItem="Gn9-HQ-HPj" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" constant="-20" id="QuP-sd-KI7"/>
                 <constraint firstItem="1Vl-Vy-gg3" firstAttribute="centerY" secondItem="ncV-eS-8Yx" secondAttribute="centerY" id="TSR-47-coa"/>
-                <constraint firstAttribute="bottom" secondItem="Bjn-zM-LJW" secondAttribute="bottom" constant="30" id="YAP-rE-Kfk"/>
+                <constraint firstItem="5FN-Gd-tjU" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="VyD-QO-Rb8"/>
                 <constraint firstItem="1Vl-Vy-gg3" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="Z4M-rM-8kS"/>
                 <constraint firstItem="ZV3-qJ-uxE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="beT-6f-OTP"/>
                 <constraint firstAttribute="bottom" secondItem="ZV3-qJ-uxE" secondAttribute="bottom" id="hv4-uE-orY"/>
@@ -63,12 +100,14 @@
                 <constraint firstItem="Gn9-HQ-HPj" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="jNQ-KE-15G"/>
                 <constraint firstItem="ncV-eS-8Yx" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" constant="17" id="lw2-0g-sel"/>
                 <constraint firstItem="Bjn-zM-LJW" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="qjV-MX-C2L"/>
+                <constraint firstItem="5FN-Gd-tjU" firstAttribute="top" secondItem="Bjn-zM-LJW" secondAttribute="bottom" constant="20" id="x3G-Gn-okq"/>
             </constraints>
             <nil key="simulatedTopBarMetrics"/>
             <nil key="simulatedBottomBarMetrics"/>
             <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
             <connections>
                 <outlet property="loadContainer" destination="Gn9-HQ-HPj" id="Rdq-mO-hMY"/>
+                <outlet property="loadWidth" destination="kYR-E7-B2J" id="3O0-7L-OzU"/>
             </connections>
             <point key="canvasLocation" x="338.40579710144931" y="-19.419642857142858"/>
         </view>

+ 90 - 2
KulexiuForStudent/KulexiuForStudent/Common/Base/KSAccompanyWebViewController.m

@@ -99,6 +99,12 @@
     [self handerAudioInterruption];
 }
 
+- (void)ignorRecordVideo {
+    if (_videoRecordManager) {
+        self.videoRecordManager.skipSaveRecord = YES;
+    }
+}
+
 - (void)stopSession {
     if (_videoRecordManager) {
         [self.videoRecordManager stopSession];
@@ -285,6 +291,8 @@
         [self.socketManager SRWebSocketClose];
         _socketManager = nil;
     }
+    // 返回不保存视频
+    [self ignorRecordVideo];
     [self stopSession];
     
     // 如果退出评测页面 清除 playerEngine
@@ -394,6 +402,8 @@
                 [self postMessage:parm];
             }
             else if ([[parm stringValueForKey:@"api"] isEqualToString:@"startCapture"]) { // 开始录制
+                // 需要合成音频
+                [self.videoRecordManager setIgnoreAudio:YES];
                 [RecordCheckManager checkPhotoLibraryPremissionAvaiable:YES showInView:self.view];
                 self.videoRecordManager.audioUrl = self.AQManager.audioUrl;
                 [self.videoRecordManager startRecord];
@@ -617,7 +627,7 @@
                 NSDictionary *content = [parm dictionaryValueForKey:@"content"];
                 int instrumentId = [content intValueForKey:@"activeMidiId"];
                 float volume = [content floatValueForKey:@"activeMidiVolume"];
-                if (instrumentId < 0) { 
+                if (instrumentId < 0) {
                     [self postMessage:parm];
                     [self.playerEngine getAllTrackVolume];
                     return;
@@ -666,6 +676,29 @@
                     [self stopTuner];
                 }
             }
+            else if ([[parm stringValueForKey:@"api"] isEqualToString:@"cloudAccompanyMessage"]) { // 获取伴奏
+                NSDictionary *content = [parm dictionaryValueForKey:@"content"];
+                NSString *accompanyUrl = [content stringValueForKey:@"accompanyUrl"];
+                if (![NSString isEmptyString:accompanyUrl]) {
+                    NSString *fileName = [[accompanyUrl componentsSeparatedByString:@"/"] lastObject];
+                    NSString *filePath = [self getAccompanyFilePathWithName:fileName];
+                    NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:filePath];
+                    if ([self checkSongHasSaveAccompanyWithSongUrl:accompanyUrl]) {
+                        [self configVideoRecord:fileUrl];
+                    }
+                    else {
+                        MJWeakSelf;
+                        [self downloadUrl:accompanyUrl success:^{
+                            [weakSelf configVideoRecord:fileUrl];
+                        } faliure:nil];
+
+                    }
+                }
+                else {
+                    [self MBShowInWindow:@"当前曲目无mp3伴奏"];
+                    [self configVideoRecord:nil];
+                }
+            }
             else {
                 [super handleScriptMessageSource:parm];
             }
@@ -675,6 +708,25 @@
 }
     
 
+- (void)downloadUrl:(NSString *)url success:(void(^)(void))success faliure:(void(^)(void))faliure {
+//    [self showhud];
+    [KSNetworkingManager downloadFileRequestWithFileUrl:url progress:^(int64_t bytesRead, int64_t totalBytes) {
+        
+    } success:^(NSURL * _Nonnull fileUrl) {
+//        [self removehub];
+        if ([self saveAccompanyFileWithUrl:fileUrl accompanyUrl:url]) {
+            success();
+        }
+        
+    } faliure:^(NSError * _Nonnull error) {
+        faliure();
+    }];
+}
+
+- (void)configVideoRecord:(NSURL *)path {
+    self.videoRecordManager.bgAudioUrl = path;
+}
+
 - (void)showBeatViewRepeatCount:(NSInteger)repeatCount supplement:(NSInteger)supplement {
     KSCloudBeatView *beatView = [KSCloudBeatView shareInstanceWithBeatType:self.beatType speed:self.currentSpeed repeatCount:repeatCount supplement:supplement];
     MJWeakSelf;
@@ -736,6 +788,8 @@
     return [filePath stringByAppendingPathComponent:fileName];;
 }
 
+
+
 - (BOOL)checkSongHasSaveWithSongUrl:(NSString *)songUrl {
     BOOL hasSaveFile = NO;
     NSString *fileName = [[songUrl componentsSeparatedByString:@"/"] lastObject];
@@ -748,7 +802,6 @@
     return hasSaveFile;
 }
 
-
 - (void)sendMessageToSocket:(NSDictionary *)parm {
     NSString *messageHeader = @"proxyMessage";
     NSString *sendMessage = [self configDataCommond:messageHeader body:[parm dictionaryValueForKey:@"content"]];
@@ -975,6 +1028,7 @@
                 
             }
         }];
+//        _videoRecordManager.bgAudioUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:@"banzou" ofType:@"mp3"]];
     }
     return _videoRecordManager;
 }
@@ -1174,6 +1228,40 @@
     NSLog(@"-------- %@%zd --- distance :%f frequence : %f" , output.pitch, output.octave, output.distance, output.frequency);
     
 }
+#pragma mark ---- 保存伴奏
+- (BOOL)saveAccompanyFileWithUrl:(NSURL *)fileUrl accompanyUrl:(NSString *)accompanyUrl {
+    NSData *sourceData = [NSData dataWithContentsOfURL:fileUrl];
+    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
+    NSString *filePath= [cachePath stringByAppendingPathComponent:@"AccompanySong"];
+    // 先创建子目录
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    if (![fileManager fileExistsAtPath:filePath]) {
+        [fileManager createDirectoryAtPath:filePath withIntermediateDirectories:YES attributes:nil error:nil];
+    }else{
+        NSLog(@"已创建文件夹");
+    }
+    NSString *fileName = [[accompanyUrl componentsSeparatedByString:@"/"] lastObject];
+    NSString *tempPath = [filePath stringByAppendingPathComponent:fileName];
+    BOOL success = [sourceData writeToFile:tempPath atomically:NO];
+    return success;
+}
+- (NSString *)getAccompanyFilePathWithName:(NSString *)fileName {
+    NSString *cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
+    NSString *filePath= [cachePath stringByAppendingPathComponent:@"AccompanySong"];
+    return [filePath stringByAppendingPathComponent:fileName];;
+}
+
+- (BOOL)checkSongHasSaveAccompanyWithSongUrl:(NSString *)songUrl {
+    BOOL hasSaveFile = NO;
+    NSString *fileName = [[songUrl componentsSeparatedByString:@"/"] lastObject];
+    NSString *filePath = [self getAccompanyFilePathWithName:fileName];
+    
+    NSFileManager *fileManager = [NSFileManager defaultManager];
+    if ([fileManager fileExistsAtPath:filePath]) {
+        hasSaveFile = YES;
+    }
+    return hasSaveFile;
+}
 
 /*
 #pragma mark - Navigation

+ 6 - 2
KulexiuForStudent/KulexiuForStudent/Common/Base/KSBaseWKWebViewController.m

@@ -132,12 +132,16 @@ typedef NS_ENUM(NSInteger, CHOOSETYPE) {
         // 切换到横屏
         AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
         delegate.allowAutoRotate = YES;
-        [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeRight inController:self];
+        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+            [UIDevice switchNewOrientation:UIInterfaceOrientationLandscapeRight inController:self];
+        });
     }
     else {
         AppDelegate* delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
         delegate.allowAutoRotate = NO;
-        [UIDevice switchNewOrientation:UIInterfaceOrientationPortrait inController:self];
+//        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+            [UIDevice switchNewOrientation:UIInterfaceOrientationPortrait inController:self];
+//        });
     }
 }
 

+ 1 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/KSLocalWebViewController.m

@@ -17,6 +17,7 @@
 @property (nonatomic, strong) NSString *currerntURL; // 当前web URL
 
 @property (nonatomic, strong) UIDocumentInteractionController *docInterCtrl;
+
 @end
 
 @implementation KSLocalWebViewController

+ 30 - 7
KulexiuForStudent/KulexiuForStudent/Common/Base/KSUploadManager.m

@@ -60,6 +60,17 @@
     [[KS3Client initialize] setBucketDomain:self.uploadBucket];
 }
 
+// 上传改造 添加目录 /yyyyMM/dd/文件名
+- (NSString *)getDayFolder {
+    NSDateFormatter *formatter = [NSObject getDateformatter];
+    [formatter setDateFormat:@"yyyyMM"];
+    NSDate *date = [NSDate date];
+    NSString *month = [formatter stringFromDate:date];
+    [formatter setDateFormat:@"dd"];
+    NSString *dayString = [formatter stringFromDate:date];
+    return [NSString stringWithFormat:@"%@/%@/",month, dayString];
+}
+
 - (void)uploadImage:(NSData *)imageData fileName:(NSString *)fileName successCallback:(KSUploadSuccess)success faliure:(KSUploadFailer)faliure {
     if (success) {
         self.successCallback = success;
@@ -67,7 +78,8 @@
     if (faliure) {
         self.faliureCallback = faliure;
     }
-    NSString *uploadFileName = [NSString stringWithFormat:@"%@-%@%@%@",UserDefault(UIDKey),[NSDate getCurrentTimestamp], fileName,[UIImage typeForImageData:imageData]];
+    NSString *folderString = [self getDayFolder];
+    NSString *uploadFileName = [NSString stringWithFormat:@"%@%@_%@%@%@",folderString,[NSDate getCurrentTimestampFor64], UserDefault(UIDKey), fileName,[UIImage typeForImageData:imageData]];
     NSString *keyValue = uploadFileName;
     [KSNetworkingManager getUploadSignRequest:KS_POST fileName:uploadFileName keyName:keyValue bucketName:self.bucketName success:^(NSDictionary * _Nonnull dic) {
         if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {
@@ -122,13 +134,20 @@
     if (faliure) {
         self.faliureCallback = faliure;
     }
+    NSString *folderString = [self getDayFolder];
     NSMutableArray *fileNameArray = [NSMutableArray array];
-    for (NSInteger i = 0 ; i < fileDataArray.count; i++) {
-        NSData *fileData = fileDataArray[i];
-        NSString *uploadFileName = [NSString stringWithFormat:@"%zd-%@-%@%@%@",i,UserDefault(UIDKey),[NSDate getCurrentTimestamp],fileName,[UIImage typeForImageData:fileData]];
+    if (fileDataArray.count > 1) {
+        for (NSInteger i = 0 ; i < fileDataArray.count; i++) {
+            NSData *fileData = fileDataArray[i];
+            NSString *uploadFileName = [NSString stringWithFormat:@"%@%@_%@%@%zd%@",folderString,[NSDate getCurrentTimestampFor64], UserDefault(UIDKey), fileName,i,[UIImage typeForImageData:fileData]];
+            [fileNameArray addObject:uploadFileName];
+        }
+    }
+    else {
+        NSData *fileData = fileDataArray[0];
+        NSString *uploadFileName = [NSString stringWithFormat:@"%@%@_%@%@%@",folderString,[NSDate getCurrentTimestampFor64], UserDefault(UIDKey), fileName,[UIImage typeForImageData:fileData]];
         [fileNameArray addObject:uploadFileName];
     }
-    
     __block NSMutableArray *sessions = [NSMutableArray array];
     __block NSMutableArray *responses = [NSMutableArray array];
     __block NSMutableArray *failResponse = [NSMutableArray array];
@@ -210,7 +229,9 @@
     if (uploadProgress) {
         self.uploadProgress = uploadProgress;
     }
-    NSString *uploadFileName = [NSString stringWithFormat:@"%@-%@%@%@",UserDefault(UIDKey),[NSDate getCurrentTimestamp], fileName,fileSuffix];
+    NSString *folderString = [self getDayFolder];
+    
+    NSString *uploadFileName = [NSString stringWithFormat:@"%@%@_%@%@%@",folderString,[NSDate getCurrentTimestampFor64], UserDefault(UIDKey),fileName,fileSuffix];
     NSString *keyValue = uploadFileName;
     self.videoLinkUrl = [NSString stringWithFormat:@"https://%@/%@",self.receiveBucket,uploadFileName];
     [KSNetworkingManager getUploadSignRequest:KS_POST fileName:uploadFileName keyName:keyValue bucketName:self.bucketName success:^(NSDictionary * _Nonnull dic) {
@@ -257,7 +278,9 @@
     if (faliure) {
         self.faliureCallback = faliure;
     }
-    NSString *uploadFileName = [NSString stringWithFormat:@"%@-%@%@%@",UserDefault(UIDKey),[NSDate getCurrentTimestamp], fileName,fileSuffix];
+    NSString *folderString = [self getDayFolder];
+    
+    NSString *uploadFileName = [NSString stringWithFormat:@"%@%@_%@%@%@",folderString,[NSDate getCurrentTimestampFor64],UserDefault(UIDKey), fileName,fileSuffix];
     NSString *keyValue = uploadFileName;
     [KSNetworkingManager getUploadSignRequest:KS_POST fileName:uploadFileName keyName:keyValue bucketName:self.bucketName success:^(NSDictionary * _Nonnull dic) {
         if ([dic integerValueForKey:@"code"] == 200 && [dic boolValueForKey:@"status"]) {

+ 3 - 0
KulexiuForStudent/KulexiuForStudent/Common/Base/KSVideoRecordManager.h

@@ -14,11 +14,14 @@ NS_ASSUME_NONNULL_BEGIN
 
 @interface KSVideoRecordManager : NSObject
 
+@property (nonatomic, strong) NSURL *bgAudioUrl;
 
 @property (nonatomic, strong) NSURL *audioUrl;
 
 @property (nonatomic, assign) BOOL ignoreAudio;
 
+@property (nonatomic, assign) BOOL skipSaveRecord;
+
 - (instancetype)initSessionRecordCallback:(KSVideoRecordCallback)callback;
 
 - (void)configSessiondisplayInView:(UIView *)containerView;

+ 10 - 7
KulexiuForStudent/KulexiuForStudent/Common/Base/KSVideoRecordManager.m

@@ -269,13 +269,16 @@
     [self.captureSession stopRunning];
     // 暂时存储文件地址
     self.videoFileURL = outputFileURL;
-   // 保存文件
-    if (_ignoreAudio == NO) {
-        [self saveVideoToAsset:self.videoFileURL];
-    }
-    else {
-        [self addBackgroundMuisc:self.audioUrl];
+    // 保存文件
+    if (self.skipSaveRecord == NO) {
+        if (_ignoreAudio == NO) {
+            [self saveVideoToAsset:self.videoFileURL];
+        }
+        else {
+            [self addBackgroundMuisc:self.audioUrl];
+        }
     }
+    self.skipSaveRecord = NO;
 }
 
 // 生成文件 合并音轨
@@ -287,7 +290,7 @@
     float audioDurationSeconds = CMTimeGetSeconds(audioDuration);
     
     NSLog(@"%f",audioDurationSeconds);
-    [KSVideoEditor addBackgroundMiusicWithVideoUrlStr:self.videoFileURL audioUrl:audioUrl start:0 end:audioDurationSeconds isOriginalSound:NO oriVolume:0 newVolume:100 completion:^(NSString * _Nonnull outPath, BOOL isSuccess) {
+    [KSVideoEditor addBackgroundMiusicWithVideoUrlStr:self.videoFileURL audioUrl:audioUrl bgAudioUrl:self.bgAudioUrl start:0 end:audioDurationSeconds isOriginalSound:NO oriVolume:0 newVolume:100 completion:^(NSString * _Nonnull outPath, BOOL isSuccess) {
         if (isSuccess) {
             [self saveVideoToAsset:[NSURL fileURLWithPath:outPath]];
         }

BIN
KulexiuForStudent/KulexiuForStudent/Common/Base/banzou.mp3


+ 3 - 0
KulexiuForStudent/KulexiuForStudent/Common/Tools/Extension/NSDate+Extension.h

@@ -235,4 +235,7 @@
 
 // get current timestamp sice 1970
 + (NSString *)getCurrentTimestamp;
+
+// get current timestamp sice 1970 base64
++ (NSString *)getCurrentTimestampFor64;
 @end

+ 10 - 0
KulexiuForStudent/KulexiuForStudent/Common/Tools/Extension/NSDate+Extension.m

@@ -705,4 +705,14 @@
     return timestamp;
 }
 
+
+// get current timestamp sice 1970 base64
++ (NSString *)getCurrentTimestampFor64 {
+    // 以下这个结果是10位数,interval得出的数会有6位小数,应该是精确到微秒
+    NSTimeInterval interval = [[NSDate date] timeIntervalSince1970] *1000000;
+    NSString *time = [[NSString stringWithFormat:@"%f",interval] replaceAll:@"." WithString:@""];
+    NSString *timestamp = time;
+    return [timestamp ks_base64EncodedString];
+}
+
 @end

+ 2 - 0
KulexiuForStudent/KulexiuForStudent/Common/Tools/VideoEditor/KSVideoEditor.h

@@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
  
  @param videoUrl 视频URL
  @param audioUrl 音频URL
+ @param bgAudioUrl 背景Url
  @param startTime 音频插入开始时间
  @param endTime 音频插入结束时间
  @param isOriginal 是否保留原声
@@ -26,6 +27,7 @@ NS_ASSUME_NONNULL_BEGIN
  */
 + (void)addBackgroundMiusicWithVideoUrlStr:(NSURL *)videoUrl
                                   audioUrl:(NSURL *)audioUrl
+                                bgAudioUrl:(NSURL *)bgAudioUrl
                                      start:(CGFloat)startTime
                                        end:(CGFloat)endTime
                            isOriginalSound:(BOOL)isOriginal

+ 33 - 3
KulexiuForStudent/KulexiuForStudent/Common/Tools/VideoEditor/KSVideoEditor.m

@@ -13,6 +13,7 @@
 
 + (void)addBackgroundMiusicWithVideoUrlStr:(NSURL *)videoUrl
                                   audioUrl:(NSURL *)audioUrl
+                                bgAudioUrl:(NSURL *)bgAudioUrl
                                      start:(CGFloat)startTime
                                        end:(CGFloat)endTime
                            isOriginalSound:(BOOL)isOriginal
@@ -20,6 +21,11 @@
                                  newVolume:(float)newVolume
                                 completion:(void (^)(NSString *outPath,BOOL isSuccess))completionHandle
 {
+    // 背景音url
+    NSURL *bgAudio_url = nil;
+    if (bgAudioUrl) {
+        bgAudio_url = bgAudioUrl;
+    }
     //音频来源路径
     NSURL   *audio_inputFileUrl = audioUrl;
     
@@ -55,7 +61,7 @@
     AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
     
     //新添加的音频
-    AVURLAsset* audioAsset =[[AVURLAsset alloc]initWithURL:audio_inputFileUrl options:nil];
+    AVURLAsset* audioAsset = [[AVURLAsset alloc]initWithURL:audio_inputFileUrl options:nil];
     AVMutableCompositionTrack *newAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
                                                                            preferredTrackID:kCMPersistentTrackID_Invalid];
     [newAudioTrack insertTimeRange:audio_timeRange
@@ -67,6 +73,23 @@
 //    [newAudioInputParams setVolumeRampFromStartVolume:newVolume toEndVolume:.0f timeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)];
     [newAudioInputParams setTrackID:newAudioTrack.trackID];
     
+    // 添加背景音URL
+    AVMutableAudioMixInputParameters *bgAudioInputParams = nil;
+    if (bgAudio_url) {
+        
+        AVURLAsset *bgAudioAsset = [[AVURLAsset alloc]initWithURL:bgAudio_url options:nil];
+        AVMutableCompositionTrack *newBgAudioTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeAudio
+                                                                               preferredTrackID:kCMPersistentTrackID_Invalid];
+        [newBgAudioTrack insertTimeRange:audio_timeRange
+                               ofTrack:[[bgAudioAsset tracksWithMediaType:AVMediaTypeAudio]objectAtIndex:0]
+                                atTime:start
+                                 error:nil];
+        
+        AVMutableAudioMixInputParameters *bgAudioInputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:newBgAudioTrack];
+        [bgAudioInputParams setTrackID:newBgAudioTrack.trackID];
+    }
+    
+    
     //视频文件原始音频通道
     if (isOriginal) {
         //视频声音采集(也可不执行这段代码不采集视频音轨,合并后的视频文件将没有视频原来的声音)
@@ -77,9 +100,16 @@
         AVMutableAudioMixInputParameters *originAudioInputParams = [AVMutableAudioMixInputParameters audioMixInputParametersWithTrack:originVoiceTrack] ;
         [originAudioInputParams setVolumeRampFromStartVolume:oriVolume toEndVolume:.0f timeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)];
         [originAudioInputParams setTrackID:originVoiceTrack.trackID];
-        audioMix.inputParameters = [NSArray arrayWithObjects:newAudioInputParams,originAudioInputParams,nil];
+        if (bgAudioInputParams) {
+            audioMix.inputParameters = [NSArray arrayWithObjects:newAudioInputParams,bgAudioInputParams,originAudioInputParams,nil];
+
+        }
+        else {
+            audioMix.inputParameters = [NSArray arrayWithObjects:newAudioInputParams,originAudioInputParams,nil];
+
+        }
     }else{
-        audioMix.inputParameters = [NSArray arrayWithObject:newAudioInputParams];
+        audioMix.inputParameters = [NSArray arrayWithObjects:newAudioInputParams,bgAudioInputParams,nil];
     }
     
     //创建一个输出

+ 1 - 0
KulexiuForStudent/KulexiuForStudent/Module/Home/View/HotMusic/HomeHotMusicCellView.m

@@ -168,6 +168,7 @@
         make.top.bottom.mas_equalTo(bgView);
     }];
 }
+
 - (IBAction)buttonAction:(id)sender {
     if (self.callback) {
         NSString *songId = [NSString stringWithFormat:@"%.0f",self.model.internalBaseClassIdentifier];

+ 3 - 3
KulexiuForStudent/KulexiuForStudent/Module/SealClass/Services/RTC/RTCService.m

@@ -147,7 +147,7 @@
             for (RCRTCInputStream *stream in remoteUser.remoteStreams) {
                 if (RTCMediaTypeVideo == stream.mediaType && [stream.tag isEqualToString:SharedScreenStreamTag]) {
                     RCRTCVideoInputStream *videoStream = (RCRTCVideoInputStream *)stream;
-                    RCRTCVideoView *remoteView = [[RCRTCVideoView alloc] init];
+                    RCRTCVideoView *remoteView = [[RCRTCVideoView alloc] initWithFrame:view.bounds];
                     remoteView.frame = view.bounds;
                     remoteView.backgroundColor = [UIColor colorWithHexString:@"3D4041" alpha:1];
                     remoteView.frameAnimated = NO;
@@ -191,7 +191,7 @@
     }
     
     if (!self.localView) {
-        self.localView = [[RCRTCVideoView alloc] init];
+        self.localView = [[RCRTCVideoView alloc] initWithFrame:view.bounds];
         self.localView.frame= view.bounds;
         self.localView.backgroundColor = [UIColor colorWithHexString:@"3D4041" alpha:1];
         self.localView.fillMode = RCRTCVideoFillModeAspectFill;
@@ -466,7 +466,7 @@
     for(RCRTCInputStream *stream in remoteUser.remoteStreams) {
         if(RTCMediaTypeVideo == stream.mediaType && ![stream.tag isEqualToString:SharedScreenStreamTag]) {
             RCRTCVideoInputStream *videoStream = (RCRTCVideoInputStream *)stream;
-            RCRTCVideoView *remoteView = [[RCRTCVideoView alloc] init];
+            RCRTCVideoView *remoteView = [[RCRTCVideoView alloc] initWithFrame:view.bounds];
             remoteView.backgroundColor = [UIColor colorWithHexString:@"3D4041" alpha:1];
             remoteView.frame = view.bounds;
             remoteView.fillMode = RCRTCVideoFillModeAspectFill;

+ 1 - 1
KulexiuForStudent/KulexiuForStudent/Module/Widget/Controller/ToneTuningViewController.m

@@ -399,7 +399,7 @@ static float correctTime = 0.5;
 
 - (NSArray *)picthDescArray {
     if (!_picthDescArray) {
-        _picthDescArray = @[@"C ins.",@"B♭ ins.",@"E♭ ins.",@"B♭ ins.",@"C ins.",@"C调大调 ins.",@"B♭ ins.",@"C ins.",@"F ins.",@"C ins.",@"B♭ ins."];
+        _picthDescArray = @[@"C ins.",@"B♭ ins.",@"E♭ ins.",@"B♭ ins.",@"C ins.",@"C ins.",@"B♭ ins.",@"C ins.",@"F ins.",@"C ins.",@"B♭ ins."];
     }
     return _picthDescArray;
 }

+ 2 - 2
KulexiuForStudent/KulexiuForStudent/Module/Widget/View/toneTuning/TunerSettingView.xib

@@ -20,8 +20,8 @@
                         <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qda-Ej-mIn">
                             <rect key="frame" x="18" y="64.000000000000028" width="235" height="45"/>
                             <subviews>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="长笛:C调" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EOf-Po-cpZ">
-                                    <rect key="frame" x="17" y="12.666666666666627" width="93" height="19.333333333333329"/>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="长笛:C调" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EOf-Po-cpZ">
+                                    <rect key="frame" x="17" y="12.666666666666627" width="76.666666666666671" height="19.333333333333329"/>
                                     <fontDescription key="fontDescription" type="system" pointSize="16"/>
                                     <color key="textColor" red="0.20000000000000001" green="0.20000000000000001" blue="0.20000000000000001" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
                                     <nil key="highlightedColor"/>