从 MOV 转换为 MP4 文件后上传为 AWS S3 中的 0 字节文件

After converting from MOV to MP4 file uploads as a 0 byte file in AWS S3

当我以原始格式 (.MOV) 上传捕获的视频文件时,TransferUtility 运行良好,但当上传转换后的文件时,它变成了 0 字节文件。

将文件从 .MOV 转换为 .MP4 后,我检查文件大小不为 0。我还必须将内容类型从 movie/quicktime 更改为 video/mp4。

这是正确的过程吗?

调用上传函数

  uploadToAWS(path: filePath, contentType: "video/mp4", key: videoname)

文件转换函数

 func exportVideo(inputurl: URL,
                 presetName: String = AVAssetExportPresetHighestQuality,
                 outputFileType: AVFileType = .mp4,
                 fileExtension: String = "mp4",
                 then completion: @escaping (URL?) -> Void)
{
        let asset = AVAsset(url: inputurl)


    let filename = filePath.deletingPathExtension().appendingPathExtension(fileExtension).lastPathComponent
    outputURL = FileManager.default.temporaryDirectory.appendingPathComponent(filename)

    if let session = AVAssetExportSession(asset: asset, presetName: presetName) {
        session.outputURL = outputURL
        session.outputFileType = outputFileType

        session.shouldOptimizeForNetworkUse = true
        session.exportAsynchronously {
            switch session.status {
            case .completed:
                completion(self.outputURL)
            case .cancelled:
                debugPrint("Video export cancelled.")
                completion(nil)
            case .failed:
                let errorMessage = session.error?.localizedDescription ?? "n/a"
                debugPrint("Video export failed with error: \(errorMessage)")
                completion(nil)
            default:
                break
            }
        }
    } else {
        completion(nil)
    }
}

上传功能

func uploadToAWS(path: URL, contentType: String, key: String) {

        exportVideo(inputurl: path, presetName: AVAssetExportPresetHighestQuality, outputFileType: .mp4, fileExtension: "mp4") { (outputURL) in

           //here i checked that the file has not 0 bytes
            do {
                let resources = try outputURL?.resourceValues(forKeys:[.fileSizeKey])
                let fileSize = resources?.fileSize!
                print ("size of this video is \(fileSize)")
            } catch {
                print("Error: \(error)")
            }

        }

        let expression = AWSS3TransferUtilityUploadExpression()
        expression.progressBlock = progressBlock

        transferUtility.uploadFile(outputURL, bucket: bucket, key: key, contentType: contentType, expression: expression, completionHandler: completionHandler).continueWith { (task) -> AnyObject? in
                if let error = task.error {
                    print("Error: \(error.localizedDescription)")
                    DispatchQueue.main.async {
                        print("failed")
                    }
                }
                if let _ = task.result {
                    DispatchQueue.main.async {
                        print("Upload Starting!")
                    }
                    // Do something with uploadTask.
                }
                return nil;
        }
    }

您的上传 (transferUtility.uploadFile(...)) 当前在 exportVideo returns 后立即开始,这仅保证 AVAssetExportSession 已创建,而不是等到它已创建完成的。把上传逻辑移到导出完成里面,应该会发现上传是对导出完成进行操作的:

func uploadToAWS(path: URL, contentType: String, key: String) {

    exportVideo(inputurl: path, presetName: AVAssetExportPresetHighestQuality, outputFileType: .mp4, fileExtension: "mp4") { (outputURL) in

        //here i checked that the file has not 0 bytes
        do {
            let resources = try outputURL?.resourceValues(forKeys:[.fileSizeKey])
            let fileSize = resources?.fileSize!
            print ("size of this video is \(fileSize)")

            let expression = AWSS3TransferUtilityUploadExpression()
            expression.progressBlock = progressBlock

            transferUtility.uploadFile(outputURL, bucket: bucket, key: key, contentType: contentType, expression: expression, completionHandler: completionHandler).continueWith { (task) -> AnyObject? in
                if let error = task.error {
                    print("Error: \(error.localizedDescription)")
                    DispatchQueue.main.async {
                        print("failed")
                    }
                }
                if let _ = task.result {
                    DispatchQueue.main.async {
                        print("Upload Starting!")
                    }
                    // Do something with uploadTask.
                }
                return nil
            }
        } catch {
            print("Error: \(error)")
        }
    }
}