Sketch JS,如何在音频标签上使用 AWS 预签名 URL?

Posted

技术标签:

【中文标题】Sketch JS,如何在音频标签上使用 AWS 预签名 URL?【英文标题】:Sketch JS, how to use AWS pre-signed URL on audio tag? 【发布时间】:2017-09-25 05:59:17 【问题描述】:

快速浏览

我在this 示例中使用Sketch.js 插件。一世 也想使用我预先签名的网址,但它们不起作用。 过期时间设置的足够长(1 天)所以有问题 与 JS 本身。

我有一个 S3 存储桶,用于存储一些受公共保护的音乐。 使用官方的 AWS 开发工具包,我可以生成如下网址:

https://d225******.cloudfront.net/song.m4a?Expires=1493381986&Signature=***&Key-Pair-Id=***

我在我的网站上使用预签名的网址没有任何问题,但在此脚本中不起作用:

<script>
var ALPHA, AudioAnalyser, COLORS, MP3_PATH, NUM_BANDS, NUM_PARTICLES, Particle, SCALE, SIZE, SMOOTHING, SPEED, SPIN;

MP3_PATH = 'my_presigned_url';

AudioAnalyser = (function() 
  AudioAnalyser.AudioContext = self.AudioContext || self.webkitAudioContext;

  AudioAnalyser.enabled = AudioAnalyser.AudioContext != null;

  function AudioAnalyser(audio, numBands, smoothing) 
    var src;
    this.audio = audio != null ? audio : new Audio();
    this.numBands = numBands != null ? numBands : 256;
    this.smoothing = smoothing != null ? smoothing : 0.3;
    if (typeof this.audio === 'string') 
      src = this.audio;
      this.audio = new Audio();
      this.audio.crossOrigin = "anonymous";
      this.audio.controls = true;
      this.audio.src = src;
    
    this.context = new AudioAnalyser.AudioContext();
    this.jsNode = this.context.createScriptProcessor(2048, 1, 1);
    this.analyser = this.context.createAnalyser();
    this.analyser.smoothingTimeConstant = this.smoothing;
    this.analyser.fftSize = this.numBands * 2;
    this.bands = new Uint8Array(this.analyser.frequencyBinCount);
    this.audio.addEventListener('canplay', (function(_this) 
      return function() 
        _this.source = _this.context.createMediaElementSource(_this.audio);
        _this.source.connect(_this.analyser);
        _this.analyser.connect(_this.jsNode);
        _this.jsNode.connect(_this.context.destination);
        _this.source.connect(_this.context.destination);
        return _this.jsNode.onaudioprocess = function() 
          _this.analyser.getByteFrequencyData(_this.bands);
          if (!_this.audio.paused) 
            return typeof _this.onUpdate === "function" ? _this.onUpdate(_this.bands) : void 0;
          
        ;
      ;
    )(this));

  

  AudioAnalyser.prototype.start = function() 
    return this.audio.play();
  ;

  AudioAnalyser.prototype.stop = function() 
    return this.audio.pause();
  ;

  return AudioAnalyser;

)();

Sketch.create(
  particles: [],
  setup: function() 
    var analyser, error, i, intro, j, particle, ref, warning, x, y;
    for (i = j = 0, ref = NUM_PARTICLES - 1; j <= ref; i = j += 1) 
      x = random(this.width);
      y = random(this.height * 2);
      particle = new Particle(x, y);
      particle.energy = random(particle.band / 256);
      this.particles.push(particle);
    
    if (AudioAnalyser.enabled) 
      try 
        analyser = new AudioAnalyser(MP3_PATH, NUM_BANDS, SMOOTHING);
        analyser.onUpdate = (function(_this) 
          return function(bands) 
            var k, len, ref1, results;
            ref1 = _this.particles;
            results = [];
            for (k = 0, len = ref1.length; k < len; k++) 
              particle = ref1[k];
              results.push(particle.energy = bands[particle.band] / 256);
            
            return results;
          ;
        )(this);
        analyser.start();
        document.getElementById('player-container').appendChild(analyser.audio);
        document.getElementsByTagName("audio")[0].setAttribute("id", "dy_wowaudio"); 
        intro = document.getElementById('intro');
        intro.style.display = 'none';
       catch (_error) 
        error = _error;
      
    
  
);
// generated by coffee-script 1.9.2
</script>

脚本在没有预签名 URL 的情况下可以正常工作(如您在上面的示例中所见),所以 我可以做些什么来在 AudioAnalyser 函数中使用我的预签名 URL

【问题讨论】:

您需要在某处...可能在 HTTP 响应标头中找到错误消息。 @Michael-sqlbot 从控制台我得到Uncaught (in promise) DOMException: Failed to load because no supported source was found. 从网络选项卡我得到Status Code:206 get from server AmazonS3 miss from Cloudfront 问题。 206 表示您只请求并收到了部分内容,这意味着您显然要提出多个请求......并暗示(但不证明)该请求不是第一个提出的,可能不是最后。您将Expires 设置在多远的未来?如果您禁用对签名 URL 的要求,并使其可以通过 CloudFront 简单地下载同一存储桶中的对象而无需签名,这是否有效?不清楚这是否正是您所说的与“正常 URL”一起使用时的意思。 @Michael-sqlbot 过期设置为 1 天。我可以在没有this 脚本的情况下在另一个页面(在音频标签中)播放这首歌。这是一个完整的工作example,带有一个普通的网址(未预签名)。 codepen 示例不想为我加载。 sketch.min.js 因“(阻塞:混合内容)”而失败。切换到 cdnjs 托管副本使其正常工作。 (cdnjs.cloudflare.com/ajax/libs/sketch.js/1.0/sketch.min.js) 【参考方案1】:

如果有,请分享您的浏览器错误消息。这可能是与 S3 存储桶数据的跨源相关的问题。

【讨论】:

正如我所说的 url 在预签名的情况下可以正常工作,这个脚本有问题。从控制台的日志中我得到 Uncaught (in promise) DOMException: Failed to load because no supported source was found. 好的,这是 Promiss 异常中的 Uncauch。写方法 autoplay 不兼容浏览器执行了类似 if (playPromise !== undefined) playPromise.then(function() // 自动播放开始!).catch(function(error) // 自动播放失败。 //显示一个 UI 元素让用户手动开始播放。); if (AudioAnalyser.enabled) try catch 为手动播放编写相同的代码。 Nirmal,meta comment here:当您想提供帮助但需要更多信息时,最好在原始问题下添加评论。【参考方案2】:

我见过 html5 视频标签发出多个请求。我假设要获取一些元数据,例如播放长度和用作缩略图的第一帧视频。您可以尝试使用 preload 属性来防止这种情况发生。

具体来说,如果剪辑很小,preload="auto" 可能就是您需要的一切。如果浏览器必须发出跟随请求,我想你会很难过。 Here's some relevant info

另一种我认为可能更可靠的解决方法是根据需要生成临时凭据。

有关更多信息,请参阅文档: - Requesting temp creds - Accessing resources with temp creds

结合用于签署 AWS 请求的 JS 包,例如在浏览器中执行此操作的 binoculars/aws-sigv4 或 copy someone else。

【讨论】:

以上是关于Sketch JS,如何在音频标签上使用 AWS 预签名 URL?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 aws 检查器资源组上多次使用相同的标签

如何在 AWS Opsworks 上设置 EC2 标签

如何在 AWS 上使用 SSL 创建 node.js 应用程序?

使用nodejs中的AWS Lambda函数上传音频文件

如何在 Internet Explorer 中播放作品音频

通过 html 音频标签在移动浏览器上播放音频