【问题标题】:DOMException: Failed to load because no supported source was foundDOMException:加载失败,因为找不到支持的源
【发布时间】:2016-10-07 01:15:45
【问题描述】:

我收到 DOMException: Failed to load because no supported source was found in video.play();线。我只有在添加 video.setAttribute('crossorigin', 'anonymous'); 后才遇到这个问题我正在开发移动应用程序,因此对于跨源,我需要添加此行。更新 chrome 50 版本后,我遇到了这个问题,然后它就可以正常工作了。

<!DOCTYPE html>
    <html>
    <head> 
       <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    </head> 
    <body>  
    <script>     
     var video = document.createElement( 'video' ); 

     video.id = 'video';    
     video.type = ' video/mp4; codecs="theora, vorbis" ';   
     video.src = "http://abcde.com/img/videos/what_is_design_thinking.mp4"; 
     video.volume = .1; 
     video.setAttribute('crossorigin', 'anonymous');    
     video.load(); // must call after setting/changing source   

     $('body').html(video);
     video.play();  

     var canvas = document.createElement('canvas');
     var ctx = canvas.getContext('2d');

     $('body').append(canvas);

     video.addEventListener('play', function() {
       var $this = this; //cache
       (function loop() {
       if (!$this.paused && !$this.ended) {
       ctx.drawImage($this, 0, 0);
       setTimeout(loop, 1000 / 30); // drawing at 30fps
       }
       })();
      }, 0);

    </script>
    </body> 
    </html>

【问题讨论】:

标签: javascript html


【解决方案1】:

这个问题出现在从 v50 开始的较新的 Chrome/Chromium 浏览器中

来自HTMLMediaElement.play() Returns a PromiseGoogle Developers

在网络上自动播放音频和视频是一项强大的功能,并且在不同平台上会受到不同的限制。今天,大多数桌面浏览器将始终允许网页通过 JavaScript 开始 &lt;video&gt;&lt;audio&gt; 播放,而无需用户交互。然而,大多数移动浏览器需要明确的用户手势才能进行 JavaScript 启动的播放。这有助于确保移动用户(其中​​许多人为带宽付费或可能在公共环境中)不会在未明确与页面交互的情况下意外开始下载和播放媒体。

过去很难确定是否需要用户交互才能开始播放,以及检测尝试(自动)播放但失败时发生的故障。存在各种变通方法,但并不理想。早就应该对底层 play() 方法进行改进以解决这种不确定性,现在它已经在 Web 平台上实现了,并在 Chrome 50 中进行了初步实现。

&lt;video&gt;&lt;audio&gt; 元素的play() 调用现在返回一个Promise。如果播放成功,则 Promise 被履行,如果播放失败,则 Promise 被拒绝,并带有解释失败的错误消息。这使您可以编写如下直观的代码:

var playPromise = document.querySelector('video').play();

// In browsers that don’t yet support this functionality,
// playPromise won’t be defined.
if (playPromise !== undefined) {
  playPromise.then(function() {
    // Automatic playback started!
  }).catch(function(error) {
    // Automatic playback failed.
    // Show a UI element to let the user manually start playback.
  });
}

除了检测 play() 方法是否成功之外,新的基于 Promise 的接口允许您确定 play() 方法何时成功。在某些情况下,Web 浏览器可能会决定延迟开始播放 - 例如,桌面 Chrome 不会开始播放 &lt;video&gt;,直到标签可见。 Promise 在实际开始播放之前不会执行,这意味着 then() 中的代码在媒体播放之前不会执行。以前确定play() 是否成功的方法,例如等待一段设定的时间等待播放事件,如果没有触发则假设失败,在延迟播放场景中容易出现误报。

致谢:Failed to load because no supported source was found. when playing HTML5 audio element

【讨论】:

  • play() 中添加promise 与问题中的DOMException 错误无关。这是一个 CORS 问题。
  • 正如上面提到的@MichaelFranzl,错误不是因为promise,当作为源提供的url上没有音频时也可能发生错误
【解决方案2】:

我遇到了同样的错误,结果证明是 CORS 问题。

而不是

video.setAttribute('crossorigin', 'anonymous');  

尝试更明确的方式:

video.crossOrigin = 'anonymous';

并确保服务器响应具有标头Access-Control-Allow-Origin: *。或者代替星号通配符,指定允许从服务器访问视频的网站域。

【讨论】:

  • 请注意,在第一个版本中,您设置的是“crossorigin”,而在第二个版本中,您设置的是“crossOrigin”,在 Origin 中使用大写 O。这可能是造成差异的原因,而不是不同的方法。
  • @PerQuestedAronsson 我认为属性名称应该都是小写的,Michael 所拥有的似乎是正确的。 developer.mozilla.org/en-US/docs/Web/HTML/Element/video
【解决方案3】:

我在 VueJS 中遇到过同样的问题。 对我有用的是替换:

const audio = new Audio(required('../assets/sound.mp3')) 
audio.play()

与:

import sound from '../assets/sound.mp3'
const audio = new Audio(sound)
audio.play()

【讨论】:

  • 效果很好,谢谢!
  • 在 Vue JS 3 中工作,工作就像一个魅力!非常感谢...
【解决方案4】:

我在使用 mp3 文件时遇到了同样的问题。 我的解决方案是通过 javascript 向 html 添加内容。

我将在其中放置要播放的文件的 HTML 示例。

<span id="audio"></span>

在 javascript 中:

$('#audio').html('<audio autoplay><source src="audio/ding.mp3"></audio>');

这将播放音频,假设它与视频相同。

希望对你有帮助

【讨论】:

    【解决方案5】:

    我遇到了同样的问题,但原因是文件名包含“#”。

    显然,如果文件名包含“#”,如果将 src 直接设置为字符串,我会得到 net::ERR_FILE_NOT_FOUND

    document.getElementById('audio').src = '../path/x#y.webm';
    console.log(document.getElementById('audio').src); // C:\Users\x\y\z\path\x#y.webm
    

    但在使用节点的path.resolve 时会得到DOMException: The element has no supported sources.,即使html 元素的src 属性相同

    document.getElementById('audio').src = path.resolve('path', 'x#y.webm');
    console.log(document.getElementById('audio').src); // C:\Users\x\y\z\path\x#y.webm
    

    将文件名重命名为 x-y.webm 解决了该问题。

    这是在 windows 上使用电子,在其他操作系统或网络应用上可能不是这样。

    【讨论】:

    • 除了重命名文件之外,是否有针对此特定问题的解决方法?谢谢
    【解决方案6】:

    如果您遇到此错误并且上述答案均不适用“ DOMException: Failed to load because no supported source was found ” 可能意味着您打开了代码而没有打开包含您要播放的音频或视频文件的文件

    【讨论】:

      【解决方案7】:

      如果您使用 http 从本地主机(例如在开发期间)为您的应用程序/站点提供服务,并且将文件存储在您使用 match() 来确定文件是否在缓存(或不缓存)。就我而言,我必须在调用 match() 时添加一个选项以将 'ignoreVary' 设置为 true,无论是在您明确进行的调用中:

      await myCache.match(filename, {ignoreVary: true}) // ignoreVary for localhost
      

      或者如果在服务工作者中使用工作箱:

      workbox.strategies.cacheOnly({
        cacheName: myCacheName,
        matchOptions: {
          ignoreVary: true, // <- this is the important bit
        },
        plugins: [
          /* bla bla */
        ]
      })
      

      参考: https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage/match https://github.com/GoogleChrome/workbox/issues/1550

      【讨论】:

        【解决方案8】:
          <!doctype html>
        <html lang="en">
        <head>
          <meta charset="utf-8">
          <title>append demo</title>
          <style>
          p {
            background: yellow;
          }
          </style>
          <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
        </head>
        <body>
        
        <p>I would like to say: </p>
        
        <script>
         var video = document.createElement( 'video' ); 
        
             video.id = 'video';    
             video.type = ' video/mp4; codecs="theora, vorbis" ';   
             video.src = "http://www.w3schools.com/html/mov_bbb.mp4"; 
        
            // $('body').html(video);
             video.play();  
             video.addEventListener('play', function() {
               var $this = this; //cache
               (function loop() {
               if (!$this.paused && !$this.ended) {      
               setTimeout(loop, 1000 / 30); // drawing at 30fps
               }
               })();
              }, 0);
        $( "p" ).append( video );
        </script>
        
        </body>
        </html>
        

        【讨论】:

        • 您应该在答案中添加更多细节,在原始帖子中指出错误,然后添加代码
        【解决方案9】:

        我在 NodeJS / Electron 应用程序中遇到了这个问题。原来是音频文件的路径不对。

        【讨论】:

          猜你喜欢
          • 2020-12-30
          • 2017-10-02
          • 2017-07-27
          • 1970-01-01
          • 2018-06-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-06
          相关资源
          最近更新 更多