swift - 如何使用 AWSS3TransferUtility 将带有用户元数据的音频文件上传到 S3
问题描述
我正在尝试允许用户将歌曲和元数据上传到 S3 文件夹。我无法上传音频(.mp3、.wav 等)。
用户信息存储在 DynamoDB 表中,但我希望将实际歌曲存储在 s3 文件夹中,并将两者连接起来。
使用以下代码,我似乎只能上传音频文件 S3 的名称,但没有实际数据......我似乎无法弄清楚。
import UIKit
import StoreKit
import AWSMobileClient
import AWSCognitoIdentityProvider
import AWSAppSync
import MediaPlayer
import AVKit
import AVFoundation
import MediaAccessibility
import MediaToolbox
class mediaUploadVC: UITableViewController, UINavigationControllerDelegate, MPMediaPickerControllerDelegate{
fileprivate let BUCKETNAME = "newtbxbkt-newtbxeniv"
var avMusicPlayer = MPMusicPlayerController.systemMusicPlayer
var mpMediapicker: MPMediaPickerController!
var mediaItems = [MPMediaItem]()
MPMusicPlayerController.systemMusicPlayer
fileprivate let s3Service: S3Service = S3Service()
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func pickSongBtn(_ sender: UIView) {
mpMediapicker = MPMediaPickerController.self(mediaTypes:MPMediaType.music)
mpMediapicker .allowsPickingMultipleItems = false
mpMediapicker .popoverPresentationController?.sourceView = sender as? UIView
mpMediapicker .delegate = self
self.present(mpMediapicker , animated: true, completion: nil)
}
func mediaPicker(_ mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
avMusicPlayer.setQueue(with: mediaItemCollection)
mediaPicker.dismiss(animated: true, completion: nil)
avMusicPlayer.play()
}
@IBAction func uploadData(_ data: Any) {
let data: Data = Data() // Data to be uploaded
let expression = AWSS3TransferUtilityUploadExpression()
expression.progressBlock = {(task, progress) in
DispatchQueue.main.async(execute: {
print("upload in progress")
// Do something e.g. Update a progress bar.
})
}
var completionHandler: AWSS3TransferUtilityUploadCompletionHandlerBlock?
completionHandler = { (task, error) -> Void in
DispatchQueue.main.async(execute: {
if let _ = error {
print ("There was an error uploading files... \(error.debugDescription)")
print ("Let us check response \(String(describing: task.response?.allHeaderFields))")
print ("Let us check response \(String(describing: task.response?.debugDescription))")
} else {
print("Completed uploading file...")
}
})
}
userAPI.getuserId { (userCognitoId) in
let transferUtility = AWSS3TransferUtility.default()
transferUtility.uploadData(data,
bucket: self.BUCKETNAME,
key: "protected/\(userCognitoId)/song1.mp3",
contentType: "audio/mp3",
expression: expression,
completionHandler: completionHandler).continueWith {
(task) -> AnyObject? in
if let error = task.error {
print("Error: \(error.localizedDescription)")
}
if let _ = task.result {
// Do something with uploadTask.
}
return nil;
}
}
}
}
解决方案
let data: Data = Data()
This is the offending line.
At the moment, you are uploading an empty Data. You’ll need to convert the file contents you wish to upload into that Data and upload that.
Edit in response to comments:
To retrieve data from a file at a given URL on the system, you can call
let fileURL: URL = ... // get a reference to the URL
if let data = try? Data(contentsOf: fileURL) {
// now you have the data
}
There is another initializer for the AWSS3TransferUtilityUploadTask
which takes the URL as an argument, which may be simpler in your case.
Getting the data of an MPMediaItem
involves getting its assetURL
, creating an AVAsset
and using an AVAssetExportSession
to write the data to a URL on the system (usually in the Temporary directory).
There are other posts here which go into more detail of how to export MPMediaItem
asset data, which you should be able to easily search for.
iOS limits you to accessing only files contained in the directories of your application (or application group) sandbox, so don't expect you will be able to get just any data from the device.
推荐阅读
- mysql - 并发用户 sql
- stata - k折交叉验证:如何根据Stata中随机生成的整数变量过滤数据
- discord.py - 有没有办法获取命令的参数?
- pandas - Plotly Dash:链式回调工作正常,但总是抛出 ValueError。如何修复或沉默?
- python - 装饰器的 Mypy 类型注释
- python - Spyder:没有名为 pywintypes 的模块
- sql - 3个字段的关系
- ios - 如何在 SwiftUI 中使视图的高度从 0 动画到高度?
- python - (Python 3) 在类中何时使用和何时不使用 Self,如何从 __init__ 传递变量
- autohotkey - 是否可以在 AHK 中同时触发 2 个热键?