当MediaElementAudioSource输出零,但是CORS不再是问题时,如何获得音频播放? [英] How can I get audio to play when MediaElementAudioSource outputs zeroes, but CORS is no longer an issue?

查看:146
本文介绍了当MediaElementAudioSource输出零,但是CORS不再是问题时,如何获得音频播放?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将<audio>实现到THREE.js场景中,并且在音频播放方面遇到了一些麻烦.在我要注销到console的数组中,所有输出均为"0".我已经通过以下方式解决了CORS问题:在audio.play();初始化之后放置了audio.crossOrigin = "anonymous",但无济于事.任何想法,将不胜感激.

I am attempting to implement <audio> into a THREE.js scene and I am having some trouble with the audio playback. In my array that I am logging out to the console, All of the output is "0". I have accounted for the CORS issue by placing this: audio.crossOrigin = "anonymous" after the audio.play(); initialization, but to no avail has this helped. Any ideas would be appreciated.

哦,我也在服务器上进行了测试,所以这不是问题.

Oh, I have also tested this with a server, so that's not the issue.

此处是回购链接.

此处是jsbin.

下面是代码.

HTML

<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>Threejs Experiment</title>
  <link rel="stylesheet" href="style.css" media="screen" title="no title" charset="utf-8">
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r73/three.min.js"></script>
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
  <script src="https://dl.dropboxusercontent.com/u/3587259/Code/Threejs/OrbitControls.js"></script>
</head>

<body>
<audio id="song" src="https://soundcloud.com/madeon/madeon-cut-the-kid"></audio>
<script type="text/javascript" src="main.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>

</body>

</html>

JavaScript

$(function(){

// Add Audio context and Audio
var ctx = new AudioContext();
var audio = document.getElementById('song');
var audioSrc = ctx.createMediaElementSource(audio);
var analyser = ctx.createAnalyser();

audioSrc.connect(analyser);
audioSrc.connect(ctx.destination);
var frequencyData = new Uint8Array(analyser.frequencyBinCount);

// Set scene and camera
var scene = new THREE.Scene();
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 100);
camera.target = new THREE.Vector3( 10, 10, 10 );

// Set the DOM
var renderer = new THREE.WebGLRenderer({ antialias:true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor("#000000");
document.body.appendChild(renderer.domElement);

// Add controls
// controls = new THREE.OrbitControls(camera, renderer );
// controls.addEventListener( 'change', render );

// Move the camera
camera.position.z = 10;
camera.position.y = 0;

// Point Lights

var pointLightBlue = new THREE.PointLight( "#00ccff", 5, 100, 2 );
pointLightBlue.position.set( -10, -40, -10 );
scene.add(pointLightBlue);

// var pointLightBlue = new THREE.PointLight( "#ffffff", 1, 0, 1 );
// pointLightBlue.position.set( -10, 20, -10 );
// scene.add(pointLightBlue);

// var pointLightPink = new THREE.PointLight( "#EE567C", 5, 100, 10 );
// pointLightPink.position.set( 1, 0, -5 );
// scene.add(pointLightPink);

var pointLight = new THREE.PointLight( "#A805FA", 100, 1000, 40 );
pointLight.position.set( 40, 0, 40 );
scene.add(pointLight);

var sphereSize = 5;
var pointLightHelper = new THREE.PointLightHelper( pointLight, sphereSize );
scene.add( pointLightHelper );

var pointLight2 = new THREE.PointLight( "#07FAA0", 100, 1000, 30 );
pointLight2.position.set( -40, 0, -40 );
scene.add(pointLight2);

var sphereSize = 5;
var pointLightHelper = new THREE.PointLightHelper( pointLight2, sphereSize );
scene.add( pointLightHelper );

var quantity = 50;
var shapes = [];


for (var i = 0; i < quantity; i++) {

    if(Math.random() < 0.5){
      var geometry = new THREE.RingGeometry( 50, 50, 18);

      // var geometries = [
            //      new THREE.IcosahedronGeometry( 20, 0 ),
            //      new THREE.OctahedronGeometry( 20, 0 ),
            //      new THREE.TetrahedronGeometry( 20, 0 ),
            //  ];
      //
            // var geometry = geometries[ Math.floor( Math.random() * geometries.length ) ];
            // var material = new THREE.MeshLambertMaterial( {
            //  color: new THREE.Color( Math.random(), Math.random() * 0.5, Math.random() ),
            //  blending: THREE.AdditiveBlending,
            //  depthTest: false,
            //  shading: THREE.FlatShading,
            //  transparent: true
            // } );
            // var mesh = new THREE.Mesh( geometry, material );
            // var wireframe = mesh.clone();
            // wireframe.material = wireframe.material.clone();
            // wireframe.material.wireframe = true;
            // mesh.add( wireframe );
            // scene.add(mesh);

      // var geometry = new THREE.RingGeometry( 20, 150, 18);

        //var geometry = new THREE.TorusKnotGeometry( 10, 3, 100, 16 );
    }
    else {
      // var geometry = new THREE.RingGeometry( 4, 40, 3);


      // var geometry = new THREE.RingGeometry( 1, 5, 6 );
      // var material = new THREE.MeshBasicMaterial( { color: 0xffff00,
      //   side: THREE.DoubleSide } );
      // var mesh = new THREE.Mesh( geometry, material );
      // scene.add( mesh );

      // var points = [];
      // for ( var j = 0; j < 10; j++ ) {
      //    points.push( new THREE.Vector3( Math.sin( j * 0.2 ) * 15 + 50, 0, ( j - 5 ) * 2 ) );
      //
      // }
      // var geometry = new THREE.LatheGeometry( points );
      // var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
      // var lathe = new THREE.Mesh( geometry, material );
      // scene.add( lathe );
    }

    if(i % 7 === 0) {
        var material = new THREE.MeshPhongMaterial( { color: "#ffffff"} );
    }
    else if(i % 2 === 0){
        var material = new THREE.MeshPhongMaterial( { color: "#666666"} );
    }
    else {
        var material = new THREE.MeshPhongMaterial( { color: "#333333"} );
    }

    var mesh = new THREE.Mesh(geometry, material);
    mesh.position.z = -i * 2;
    mesh.rotation.z = i;
    shapes.push(mesh);
    scene.add(mesh);
}

// Variables
var u_time = 0;

// Render function
var render = function() {
    requestAnimationFrame(render);
    u_time++;

    for (var i = 0; i < quantity; i++) {

        // Set rotation change of shapes
        shapes[i].position.z += 0.2;
        shapes[i].rotation.z += 0;
        shapes[i].scale.x = 1 + Math.sin(i + u_time * 0.1) * 0.05;
        shapes[i].scale.y = 1 + Math.sin(i + u_time * 0.1) * 0.05;

        var change = 1.5 + Math.sin(u_time * 0.5) * 0.5;

        // Set wireframe & width
        if(Math.random() < change){
            shapes[i].material.wireframe = true;
            shapes[i].material.wireframeLinewidth = Math.random() * 2;
        }
        else {
            shapes[i].material.wireframe = false;
        }

        if(shapes[i].position.z > 10){
            shapes[i].position.z = -70;
            shapes[i].rotation.z = i;
        }
    }

    // Set Point light Intensity & Position
    pointLight.intensity = Math.abs(Math.sin(u_time * 0.2) * 2);
    pointLight2.intensity = Math.abs(Math.cos(u_time * 0.2) * 2);
    pointLight.position.z = Math.abs(Math.sin(u_time * 0.02) * 30);
    pointLight2.position.z = Math.abs(Math.cos(u_time * 0.02) * 30);

    // camera.rotation.y = 90 * Math.PI / 180;
    // camera.rotation.z = frequencyData[20] * Math.PI / 180;
    // camera.rotation.x = frequencyData[100] * Math.PI / 180;
    console.log(frequencyData);

    //composer.render();
    renderer.render(scene, camera);

}
audio.play();
// audio.crossOrigin = "anonymous";
render();
});

推荐答案

"CORS没问题"是什么意思?

What do you mean "CORS isn't an issue"?

  1. 如果音频来自其他来源,则需要设置crossOrigin属性之前设置src属性

someAudioElement.crossOrigin = "anonymous";

换句话说,要么将crossOrigin属性放在标签本身中

In other words either put the crossOrigin property in the tag itself

<audio crossOrigin="anonymous" src="http://somedomain/someaudio">...

或者使用JavaScript

Or in JavaScript

someAudioElement.crossOrigin = "anonymous";
someAudioElement.src = "http://somedomain/someaudio";

之所以必须这样做,是因为设置了src属性后,浏览器将尝试获取音频.如果尚未设置crossOrigin属性,则浏览器将不会询问使用音频的权限.

The reason you have to do this before is because the moment you set the src property the browser will try to get the audio. If you haven't already set the crossOrigin property the browser won't know to ask for permission to use the audio.

请注意,所有要做的就是向服务器请求权限.服务器本身仍然必须授予浏览器使用音频的权限.大多数服务器不授予此权限. Soundcloud并非适用于所有歌曲.

Note that all that does is ask the server for permission. The server itself still has to give permission to the browser to use the audio. Most servers do not give this permission. Soundcloud does but not for all songs.

iOS上的Safari和Android上的Chrome不支持分析流音频数据.

Safari on iOS and Chrome on Android don't support analysing streaming audio data.

您可以跟踪 Chrome问题以在此处解决此问题 .如果要跟踪进度,请为它加注星标.我不知道是否有 webkit错误可以在iOS上跟踪问题

You can track the Chrome issue to fix this here. Star it if you want to track the progress. I don't know if there is a webkit bug to track the issue on iOS

AFAIK,您不能直接播放音云URL

AFAIK you can't play soundcloud URLs directly

您有这样的代码

<audio id="song" src="https://soundcloud.com/madeon/madeon-cut-the-kid"></audio>

这不是Soundcloud音频的有效URL.您必须将该URL连同API密钥一起传递到soundcloud API,它将为您提供正确的URL.

That is not a valid URL for soundcloud audio. You have to pass that URL to the soundcloud API along with an API key and it will give you back a correct URL.

这是一个关于SO的问题

其他注意事项:

  • soundcloud SDK 3.0 SDK在Safari上无法用于分析音频.使用soundcloud SDK 2.0或更高版本,请使用直接XMLHttpRequest,因为soundcloud SDK 2.0会初始化闪存,即使您不使用它也是如此.

  • The soundcloud SDK 3.0 SDK doesn't work on Safari for analysing audio. Use the soundcloud SDK 2.0 or better, use a direct XMLHttpRequest because the soundcloud SDK 2.0 initializes flash even if you don't use it.

使用soundcloud sdk 2.0的示例

Example using the soundcloud sdk 2.0

以HTML

<script src="https://connect.soundcloud.com/sdk-2.0.0.js"></script> 

在Java语言中

// see https://auth0.com/docs/connections/social/soundcloud
var yourSoundCloudClientId = "???????";
SC.initialize({
  client_id: yoursCoundCloudClientId,
});

var soundCloudURL = "https://soundcloud.com/madeon/madeon-cut-the-kid";
SC.get("/resolve", { url: soundCloudUrl }, function(result, err) {
  if (err) {
    console.error("bad url:", url, err);
    return;
  }
  if (result.streamable && result.stream_url) {
    var src = result.stream_url + '?client_id=' + yourSoundCloudClientId;
    someAudioElement.crossOrigin = "anonymous";
    someAudioElement.src = src;

    // other things you might be interested in because
    // if you use soundcloud music you're required to give
    // and display attribution and links

    console.log("link to music:", result.permalink_url);
    console.log("link to band:", result.user.permalink_url);
    console.log("name of song:", result.title);
    console.log("name to band:", result.user.username);
  } else {
     console.error("not streamable:", url);
  }
});

此示例无需Soundcloud SDK.

This example does it without the soundcloud SDK.

这篇关于当MediaElementAudioSource输出零,但是CORS不再是问题时,如何获得音频播放?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆