如何为音频文件数组的每个索引动态绑定src值到指令作用域变量



我在AngularJS应用程序中使用了一个使用D3.js和Web Audio API的音乐频率可视化器。

我在里面创建了一个自定义的bower组件,里面有一个指令和一个templateUrl html文件。

Directive.js

(function (angular) {
	var ap=angular.module('audio-player-mod',[]);
	ap.directive('audioPlayer', function () {
		 return {
		    restrict: 'EA',
		    scope: {
		      audioFile : "="		      
		    },
		link: function (scope,element,attrs) {
			$(document).ready(function () {				
			
			// scope.audios=scope.audioFile;
			console.log(scope.audioFile);
			  
			  var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
			  var audioElement = document.getElementById('audioElement');
			  var audioSrc = audioCtx.createMediaElementSource(audioElement);
			  var analyser = audioCtx.createAnalyser();
  
			  // Bind our analyser to the media element source.
			  audioSrc.connect(analyser);
			  audioSrc.connect(audioCtx.destination);
			  //var frequencyData = new Uint8Array(analyser.frequencyBinCount);
			  var frequencyData = new Uint8Array(200);
			  var svgHeight = '500';
			  var svgWidth = '2000';
			  var barPadding = '1';
			  function createSvg(parent, height, width) {
			    return d3.select(parent).append('svg').attr('height', height).attr('width', width);
			  }
			  var svg = createSvg('body', svgHeight, svgWidth);
			  // Create our initial D3 chart.
			  svg.selectAll('rect')
			     .data(frequencyData)
			     .enter()
			     .append('rect')
			     .attr('x', function (d, i) {
			        return i * (svgWidth / frequencyData.length);			
			     })
			     .attr('width', svgWidth / frequencyData.length - barPadding);
			  // Continuously loop and update chart with frequency data.
			  function renderChart() {
			     requestAnimationFrame(renderChart);
			     // Copy frequency data to frequencyData array.
			     analyser.getByteFrequencyData(frequencyData);
			     // Update d3 chart with new data.
			     svg.selectAll('rect')
			        .data(frequencyData)
			        .attr('y', function(d) {
			           return svgHeight - d;
			        })
			        .attr('height', function(d) {
			           return d;
			        })
			        .attr('fill', function(d) {
			           return 'rgb(0, 0, ' + d + ')';
			        });
			  }
			  // Run the loop
			  renderChart();
			});
		
		},
		    templateUrl: 'bower_components/audio-player/view/audio-player.html'
		};
	});
})(angular);

templateUrl.html(这里是audio-player.html)

<div>
 	<audio id="audioElement" crossorigin="anonymous" src="audioFile"></audio>
    <div>
      <button onclick="document.getElementById('audioElement').play()">Play</button>
      <button onclick="document.getElementById('audioElement').pause()">Pause</button>
      <button onclick="document.getElementById('audioElement').volume+=0.1">Increase Volume</button>
      <button onclick="document.getElementById('audioElement').volume-=0.1">Decrease Volume</button>
    </div>
    </div>

和这个audioPlayer指令在视图中的另一个html文件中使用,代码如下

<div class="player-region" ng-if="recordingsCtrl.audioList[0].src">
    <div>
    <div class="player-control">
      <div class="player-control-bottom">
        <audio-player crossorigin="anonymous" audio-file="recordingsCtrl.audioList[0].src"></audio-player>
      </div>
    </div>
    </div>
  </div>

这里audio-player标签中的src值可以从directive.js (directive的名字是audioPlayer)文件

我尝试在视图中打印{{audioFile}},它显示了每个音频索引的url,

问题是我如何在指令范围变量中获得src的值?我得到它的第一次点击,但当我点击另一个索引,范围没有得到更新的src值!!

我尝试重新加载指令,在html文件中设置一个标志

<div ng-if="recordingsCtrl.songChanged">
        <audio-player  crossorigin="anonymous" audio-file="recordingsCtrl.audioList[0].src"></audio-player>
      </div>

,然后设置每个音频文件点击的超时功能,

function playAudio{
self.songChanged = false;
      setTimeout(function() {
        self.songChanged = true;
        $scope.$apply();
      }, 10);
  
  }

对于第一次加载窗口,该指令将被绑定到html,然后如果我们想要改变指令的范围变量,我们可以通过重新加载指令来做到这一点,就像上面的

这是我们解决这个问题的方法之一,如果你们谁有更好的解决方案,请在下面回答。

最新更新