Bladeren bron

添加音频合成

rhyme 5 jaren geleden
bovenliggende
commit
65a4240a1f

+ 3 - 5
.idea/workspace.xml

@@ -1,9 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ChangeListManager">
-    <list default="true" id="96a4f947-f66a-4efc-b495-ae979b3315bb" name="Default Changelist" comment="">
-      <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-    </list>
+    <list default="true" id="96a4f947-f66a-4efc-b495-ae979b3315bb" name="Default Changelist" comment="" />
     <ignored path="$PROJECT_DIR$/.dart_tool/" />
     <ignored path="$PROJECT_DIR$/.idea/" />
     <ignored path="$PROJECT_DIR$/.pub/" />
@@ -109,7 +107,6 @@
     </navigator>
     <panes>
       <pane id="Scope" />
-      <pane id="PackagesPane" />
       <pane id="ProjectPane">
         <subPane>
           <expand>
@@ -131,6 +128,7 @@
           <select />
         </subPane>
       </pane>
+      <pane id="PackagesPane" />
     </panes>
   </component>
   <component name="PropertiesComponent">
@@ -174,7 +172,7 @@
   <component name="ToolWindowManager">
     <frame x="94" y="23" width="1346" height="877" extended-state="0" />
     <layout>
-      <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.21395706" />
+      <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.21702453" />
       <window_info id="Captures" order="1" side_tool="true" />
       <window_info id="Structure" order="2" side_tool="true" />
       <window_info id="Image Layers" order="3" />

BIN
android/.gradle/5.4.1/executionHistory/executionHistory.bin


BIN
android/.gradle/5.4.1/executionHistory/executionHistory.lock


BIN
android/.gradle/5.4.1/fileHashes/fileHashes.bin


BIN
android/.gradle/5.4.1/fileHashes/fileHashes.lock


BIN
android/.gradle/buildOutputCleanup/buildOutputCleanup.lock


BIN
android/.gradle/buildOutputCleanup/outputFiles.bin


BIN
android/.idea/caches/build_file_checksums.ser


+ 2 - 2
android/local.properties

@@ -4,5 +4,5 @@
 # Location of the SDK. This is only used by Gradle.
 # For customization when using a Version Control System, please read the
 # header note.
-#Wed Oct 30 09:43:53 CST 2019
-sdk.dir=C\:\\androidsdk\\androidsdk\\android-sdk-windows
+#Mon Jan 13 10:51:19 CST 2020
+sdk.dir=/Users/lipenghui/Library/Android/sdk

+ 2 - 2
android/src/main/kotlin/cn/i2edu/dubbing_lib/DubbingLibPlugin.kt

@@ -99,7 +99,7 @@ class DubbingLibPlugin : MethodCallHandler {
                                     pathBgmDecodeDir = call.argument<String>("pathBgmDecode")!!, pathBgmRecordSyncDir = call.argument<String>("pathBgmRecordSync")!!,
                                     pathBgmRecordDecodeSyncDir = call.argument<String>("pathBgmRecordDecodeSync")!!, pathVideoMixinDir = call.argument<String>("pathVideoMixin")!!)
                             .setComposeCallBack(
-                                    object: MixinVideoCallBack {
+                                    object : MixinVideoCallBack {
                                         override fun onResult(resultPath: String) {
                                             activity.runOnUiThread {
                                                 result.success(resultPath)
@@ -127,7 +127,7 @@ class DubbingLibPlugin : MethodCallHandler {
                                     audioDecodePath = call.argument<String>("audioDecodePath")!!, mixinFilePath = call.argument<String>("mixinFilePath")!!,
                                     encodePath = call.argument<String>("encodePath")!!)
                             .setComposeCallBack(
-                                    object: MixinPaintedCallBack {
+                                    object : MixinPaintedCallBack {
                                         override fun onResult(resultPath: String) {
                                             activity.runOnUiThread {
                                                 result.success(resultPath)

+ 20 - 15
ios/Classes/DubbingComposer.swift

@@ -11,12 +11,12 @@ import AVFoundation
 
 class DubbingComposer {
     var timeline: [Double]
-    var videoUrl: URL
+    var videoUrl: URL?
     var musicUrl: URL
     var recordsUrl: [String]
     var preTime: Double = 0
     
-    init(timeline: [Double], videoUrl: URL, musicUrl: URL, recordsUrl: [String]){
+    init(timeline: [Double], videoUrl: URL?, musicUrl: URL, recordsUrl: [String]){
         self.timeline = timeline
         self.videoUrl = videoUrl
         self.musicUrl = musicUrl
@@ -28,26 +28,31 @@ class DubbingComposer {
         //初始化合成器
         let composition = AVMutableComposition()
         
+        var videoTimeRange:CMTimeRange?
+        
         //为合成器添加视频轨道
-        let videoTrack = composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)
-        let videoAsset = AVURLAsset(url: videoUrl, options: nil)
-        let videoTimeRange = CMTimeRangeMake(start: CMTime.zero, duration: videoAsset.duration)
-        do {
-            try videoTrack?.insertTimeRange(videoTimeRange, of: videoAsset.tracks(withMediaType: AVMediaType.video).first!, at: CMTime.zero)
-        }
-        catch {
-            DispatchQueue.main.async(execute: { 
-                failBlock?("Fail on load video")
-            })
-            return
+        if((videoUrl) != nil){
+           let videoTrack = composition.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid)
+            let videoAsset = AVURLAsset(url: videoUrl!, options: nil)
+            videoTimeRange = CMTimeRangeMake(start: CMTime.zero, duration: videoAsset.duration)
+            do {
+                try videoTrack?.insertTimeRange(videoTimeRange!, of: videoAsset.tracks(withMediaType: AVMediaType.video).first!, at: CMTime.zero)
+            }
+            catch {
+                DispatchQueue.main.async(execute: {
+                    failBlock?("Fail on load video")
+                })
+                return
+            }
         }
+            
         
         //添加音乐轨道
         let musicTrack = composition.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid)
         let musicAsset = AVURLAsset(url: musicUrl, options: nil)
-        let musicTimeRange = videoTimeRange
+        let musicTimeRange = (videoTimeRange) != nil ? videoTimeRange: CMTimeRangeMake(start: CMTime.zero, duration: musicAsset.duration)
         do {
-            try musicTrack?.insertTimeRange(musicTimeRange, of: musicAsset.tracks(withMediaType: AVMediaType.audio).first!, at: CMTime.zero)
+            try musicTrack?.insertTimeRange(musicTimeRange!, of: musicAsset.tracks(withMediaType: AVMediaType.audio).first!, at: CMTime.zero)
             print("创建音乐音轨成功")
         }
         catch {

+ 25 - 3
ios/Classes/SwiftDubbingLibPlugin.swift

@@ -66,6 +66,13 @@ public class SwiftDubbingLibPlugin: NSObject, FlutterPlugin {
             let outPath = pathVideoMixinDir + "\(videoId)_mix.mp4";
             startMixinAudio(videoPath: videoPath, bgmPath: bgmPath, audioPathList: audioPathList, startTimeList: startTimeList, outPath: outPath, result: result)
             break
+        case "startMixinPaintedAudio":
+            let bgmPath = args!["bgmPath"] as! String;
+            let audioPathList = args!["audioPaths"] as! [String];
+            let startTimeList = args!["durationList"] as! [Double];
+            let pathVideoMixinDir = args!["encodePath"] as! String;
+            startMixinAudio(videoPath: nil, bgmPath: bgmPath, audioPathList: audioPathList, startTimeList: startTimeList, outPath: pathVideoMixinDir, result: result)
+            break;
         case "getIsMediaPlayPause":
             result(audioPlayer != nil && audioPlayer!.isPlaying)
             break
@@ -99,10 +106,10 @@ public class SwiftDubbingLibPlugin: NSObject, FlutterPlugin {
     }
     
     /// 合成
-    func startMixinAudio(videoPath: String, bgmPath: String, audioPathList: [String], startTimeList: [Double], outPath: String, result: @escaping FlutterResult) {
-        let videoUrl = URL(fileURLWithPath: videoPath)
+    func startMixinAudio(videoPath: String?, bgmPath: String, audioPathList: [String], startTimeList: [Double], outPath: String, result: @escaping FlutterResult) {
+        let videoUrl:URL? = videoPath.isBlank ?URL(fileURLWithPath: videoPath!):nil
         let musicUrl = URL(fileURLWithPath: bgmPath)
-        let composer = DubbingComposer(timeline: startTimeList, videoUrl: videoUrl, musicUrl: musicUrl, recordsUrl: audioPathList)
+        let composer = DubbingComposer(timeline: startTimeList, videoUrl: videoUrl!, musicUrl: musicUrl, recordsUrl: audioPathList)
         composer.preTime = preLag
         let outputUrl = URL(fileURLWithPath: outPath)
         DispatchQueue.global().async {
@@ -220,3 +227,18 @@ extension SwiftDubbingLibPlugin: AVAudioPlayerDelegate {
         //        self.result!(false)
     }
 }
+
+extension String{
+    
+    /// check string cellection is whiteSpace
+    var isBlank : Bool{
+        return allSatisfy({$0.isWhitespace})
+    }
+}
+
+
+extension Optional where Wrapped == String{
+    var isBlank : Bool{
+        return self?.isBlank ?? true
+    }
+}