0

我有一个使用 Amplify 作为后端的 IOS 项目。我还加入了 Amplify Video 以支持视频点播。将 Amplify Video 添加到项目后,会生成“输入”和“输出”存储桶。当通过 Amplify 控制台进行可视化时,这些会出现在我的项目环境之外。它们只能通过导航到 AWS S3 控制台来访问。我的问题是,如何通过 Amplify 将我的视频通过 swift 上传到“输入”存储桶(或者我不上传)?我下面的代码将视频上传到项目环境中的 S3 存储桶。几乎不支持 Amplify Video for IOS(Amplify Video 文档

if let vidData = self.convertVideoToData(from: srcURL){
                let key = "myKey"
                //let options = StorageUploadDataRequest.Options.init(accessLevel: .protected)
                Amplify.Storage.uploadData(key: key, data: vidData) { (progress) in
                    print(progress.fractionCompleted)
                } resultListener: { (result) in
                    switch result{
                    case .success(_ ):
                        print("upload success!")
                    case .failure(let error):
                        print(error.errorDescription)
                    }
                }
            }
4

1 回答 1

0

我面临同样的问题。据我所知,iOS Amplify 库amplifyconfiguration.json仅限于使用S3TransferUtility.

我自己正在解决这个问题,但快速的解决方案是修改创建的 AWS 视频资源以运行相同的存储桶(输入和输出)。现在,请注意,我是一名 iOS 工程师,不是后端,只是熟悉 AWS。

解决方法如下:

  • 放大视频插件创建的输入桶在属性选项卡下有 4 个事件通知。这些都启动了一个 VOD-inputWatcher lambda 函数。将这 4 个通知复制到您的原始存储桶
  • 输出存储桶有两个事件通知,将它们也复制到原始存储桶

立即尝试该过程,手动将视频放入您的存储桶中。它会失败,但我们会看到进展 - MediaConvert 作业已启动,但会告诉您它失败,因为它没有读取存储桶中文件的权限。类似的东西Unable to open input file, Access Denied。让我们解决这个问题:

  • 转到输入 lambda 函数并添加此函数:
async function enableACL(eventObject) {
  console.log(eventObject);
    const objectKey = eventObject.object.key;
    const bucketName = eventObject.bucket.name;
    const params = {
      Bucket: bucketName,
      Key: objectKey,
      ACL: 'public-read',
    };
    console.log(`params: ${eventObject}`);
    s3.putObjectAcl(params, (err, data) => {
      if (err) {
        console.log("failed to set ACL");
        console.log(err);
      } else {
        console.log("successfully set acl");
        console.log(data);
      }
    });
}

现在从事件处理程序中调用它,并且不要忘记const s3 = new AWS.S3({});在文件顶部添加:

exports.handler = async (event) => {
  
  // Set the region
  AWS.config.update({ region: event.awsRegion });
  console.log(event);
  if (event.Records[0].eventName.includes('ObjectCreated')) {
    await enableACL(event.Records[0].s3);
    await createJob(event.Records[0].s3);
    const response = {
      statusCode: 200,
      body: JSON.stringify(`Transcoding your file: ${event.Records[0].s3.object.key}`),
    };
    return response;
  }
};

再次尝试该过程。lambda 将失败,您可以在 lambda 的 CloutWatch: 中看到它failed to set ACL. INFO AccessDenied: Access Denied at Request.extractError。为了解决这个问题,我们需要向输入 lambda 函数授予 S3 权限。

通过导航到 lambda 函数的配置/权限并找到角色来做到这一点。在 IAM 中打开它并添加完整的 S3 访问权限。不理想,但同样,我只是想让这项工作。仅指定确切的 Bucket 和正确的操作可能会更好。非常感谢有关适当角色的任何帮助:)

对输出 lambda 函数的角色也重复相同的操作,为其提供正确的 S3 权限。

再次尝试上传文件。此时如果你遇到这个错误: failed to set ACL. INFO NoSuchKey: The specified key does not exist. at Request.extractError。这是因为在存储桶中,您的protected文件夹中有对象。尝试改用公用文件夹(在 iOS 库中,您必须使用StorageAccessLevel.guest权限才能访问它)

现在在文件夹中放置一个文件public。您应该会看到 MediaConvert 作业再次启动。它仍然会失败(检查 MediaConvert / Jobs),说它没有写入 S3 存储桶的权限Unable to write to output file ..。您可以通过再次转到输入 lambda 函数来解决此问题,这将授予 MediaConvert 作业的权限:

const jobParams = {
    JobTemplate: process.env.ARN_TEMPLATE,
    Queue: queueARN,
    UserMetadata: {},
    Role: process.env.MC_ROLE,
    Settings: jobSettings,
  };
  await mcClient.createJob(jobParams).promise();

转到输入 lambda 函数,配置/环境变量。该函数使用该字段MC_ROLE为媒体转换作业提供角色名称。复制角色名称并在 IAM 中查找。通过将对角色的正确 S3 访问权限添加到您的存储桶来修改其权限。

如果您只尝试更多时间,输出应该会出现在您的输入文件旁边。

为了能够s3://public/{userIdentityId}/{videoName}/{videoName}{quality}..m3u8使用 iOS 中的当前Amplify.Storage.downloadFile(key: {key}, ...)函数读取文件,您可能必须附加到密钥正确路径并删除.mp4扩展名。如果您遇到任何问题,请告诉我,我现在也在整理。

于 2021-04-25T10:09:08.880 回答