我有一个音频文件列表,显示为链接和<audio>
html5播放器。每个链接都会调用一个函数来更改<source>
中<audio>
标记的src:
<audio controls="controls" preload="none">
<source type="audio/mpeg" src="{{selectedSongPath}}"/>
</audio>
...
<div class="songEntry" ng-repeat="song in songs">
<a href="" ng-click="songSelect(song.path)">{{song.name}}</a>
</div>
...
$scope.songSelect = function(songPath) {
$scope.selectedSongPath = songPath;
}
我可以看到src正在改变,但没有播放。路径还可以;如果我用其中一条路径初始化src,播放器就可以工作。
我做错了什么?
答案 0 :(得分:25)
以下是几种有棱角的方法:
1)使用ng-src =而不是src =
角度文档解释了为什么这样有效: http://docs.angularjs.org/api/ng.directive:ngSrc
在编译阶段,angular会扩展元素以包含正确的src =属性。
这将改变HTML5音频元素的src属性,但不幸的是,这还不足以制作新的歌曲。你需要通过调用.play()方法来促使音频元素做某事。
糟透了:(
进一步黑客沿着同样的路径建议在控制器内部进行DOM操作。这通常表明这是错误的解决方案。
更好的解决方案是使用服务!!!
2)使用角度服务的音频
// Define a simple audio service
mpApp.factory('audio',function ($document) {
var audioElement = $document[0].createElement('audio'); // <-- Magic trick here
return {
audioElement: audioElement,
play: function(filename) {
audioElement.src = filename;
audioElement.play(); // <-- Thats all you need
}
// Exersise for the reader - extend this service to include other functions
// like pausing, etc, etc.
}
});
现在,在您的控制器中,您可以注入“音频”,并做任何您需要做的事情。
例如:
function myAstoundingAudioCtrl($scope, audio) { //<-- NOTE injected audio service
$scope.songSelect = function(songPath) {
audio.play(songPath); // <--- Thats All You Need !
}
}
现在,您可以将'audio'作为参数添加到任何需要的控制器中 更改音乐,并使用此处定义的相同API调用。
作为'服务',整个应用程序只有一个实例。所有对“audio”的调用都指向同一个对象。这对于角度的所有服务都是如此。正是在这种情况下我们需要的。
该服务在应用程序的根文档上创建一个不可见的HTML5元素,因此无需在任何地方的视图上添加标记。当用户导航到不同的视图时,这还有保持播放歌曲的额外好处。
请参阅http://docs.angularjs.org/api/ng。$ document以了解$ document service的定义。
希望有助于交配:)
答案 1 :(得分:20)
即使在使用$ sce.trustAsResourceUrl之后我也遇到了同样的问题,然后我意识到问题出在HTML上。源应该放在音频标签本身:
<audio controls data-ng-src="{{yourTrustedUrl}}" ></audio>
答案 2 :(得分:5)
<audio ng-src="{{getAudioUrl()}}" audioplayer controls></audio>
$scope.getAudioUrl = function() {
return $sce.trustAsResourceUrl('your url');
};
这对我有用,你需要消毒你
答案 3 :(得分:4)
ngSrc不适用于AngularJS中的视频,仅适用于图像。我的解决方案是:
在视图中:
<video controls="controls" name="Video Name" ng-src="{{getVideoUrl()}}"></video>
在控制器中:
$scope.getVideoUrl=function(){
return $sce.trustAsResourceUrl("media/"+$scope.groupedProjList[$scope.routeId].CONTACTNAME+".mp4");
};
用你的网址替换我的网址:
$sce.trustAsResourceUrl('your Url');
不要忘记将$sce
添加到您的模块中:
angular.module('myApp.controllers', [])
.controller('MyCtrl1', function($scope,$http,$routeParams,$sce) {
答案 4 :(得分:2)
我在使用下拉菜单加载视频源时遇到了类似的问题。我发现$scope.$apply();
是我需要添加的全部内容。没有时间来接受你的代码并测试这个实现,但我建议你试试这个:
$scope.songSelect = function(songPath) {
$scope.selectedSongPath = songPath;
$scope.$apply();
}
关于使用$scope.$apply()
处理错误存在一些争议。我认为正确的实施实际上如下:
$scope.songSelect = function(songPath) {
$scope.$apply(function() {
$scope.selectedSongPath = songPath;
});
}
如果songPath
返回undefined,这应该会更好地应对;唉,我找不到我学习这个技巧的链接。如果我这样做,我会将其作为对此答案的评论发布。
希望这会有所帮助:)
答案 5 :(得分:1)
您也可以使用:
<div ng-bind-html-unsafe="audioPlayer"></div>
在您的控制器上:
$scope.audioPlayer="<br /><audio controls><source src=\""+ audiosource + "\" type=\"audio/mpeg\"> Your browser does not support the audio element. </audio>"
注意:
仅当ngBindHtml指令也是如此时,您应该使用此指令 限制性,当你完全信任内容的来源时 你有约束力。
更多here
答案 6 :(得分:1)
@SteveOC 64的方法涉及创建音频的新实例。如果您已有音频标签,如
<audio id="audio" controls></audio>
您可以尝试以下代码
app.factory('audio', function($document) {
var audioElement = $document[0].getElementById('audio');
audioElement.autoPlay = true; // as per your requirement
return {
audioElement: audioElement,
play: function(filename) {
audioElement.src = filename;
audioElement.play();
},
resume: function() {
audioElement.play();
},
pause: function() {
audioElement.pause();
},
stop: function() {
audioElement.pause();
audioElement.src = audioElement.currentSrc; /** http://stackoverflow.com/a/16978083/1015046 **/
},
incVol: function() {
if (audioElement.volume < 1) {
audioElement.volume = (audioElement.volume + 0.1).toFixed(2);
}
return audioElement.volume;
},
decVol: function() {
if (audioElement.volume > 0) {
audioElement.volume = (audioElement.volume - 0.1).toFixed(2);
}
return audioElement.volume;
},
timer: function(callback) {
audioElement.ontimeupdate = function() {
callback(audioElement.duration, audioElement.currentTime)
};
},
}
});
在注入audio
工厂后的控制器中,您可以将其称为
audio.play('/api/resource?resource=' + uri);
如果这是一个事件驱动,就像在播放音频时点击另一个元素
$scope.$apply(function() {
$scope.audioPlayer = true;
audio.play('/api/resource?resource=' + uri);
$scope.isAudioPlaying = true;
});
如果有人在寻找视频工厂:
HTML
<video id="video" controls></video>
厂
app.factory('video', function($document) {
var videoElement = $document[0].getElementById('video');
videoElement.autoPlay = true;
return {
videoElement: videoElement,
play: function(filename) {
videoElement.src = filename;
videoElement.play();
},
resume: function() {
videoElement.play();
},
pause: function() {
videoElement.pause();
},
stop: function() {
videoElement.pause();
videoElement.src = videoElement.currentSrc; /** http://stackoverflow.com/a/16978083/1015046 **/
},
incVol: function() {
if(videoElement.volume < 1) {
videoElement.volume = (videoElement.volume + 0.1).toFixed(2);
}
return videoElement.volume;
},
decVol: function() {
if(videoElement.volume > 0) {
videoElement.volume = (videoElement.volume - 0.1).toFixed(2);
}
return videoElement.volume;
},
timer: function(callback) {
videoElement.ontimeupdate = function() {
callback(videoElement.duration, videoElement.currentTime)
};
},
}
});
您可以将其作为video.play('/api/resource?resource=' + uri);
希望这有帮助!
答案 7 :(得分:1)
我找到的解决方案是在从ajax调用中获取视频网址后立即加载视频。
var video = angular.element('#video_id');
video.load();
答案 8 :(得分:0)
从未尝试使用audio
代码,但src
应该进行插值,因此应该在{{}}
之间。
<audio controls="controls" preload="none">
<source type="audio/mpeg" src="{{selectedSongPath}}"/>
</audio>
你有没试过这个?
答案 9 :(得分:0)
更改src后,您还必须加载该文件,因此请尝试在songselect
之后添加到您的函数$scope.selectedSongPath = songPath;
:
$scope.load();
我不知道你的情况是什么$ scope,但load()
方法应该在你的音频标签的对象内执行。在简单的JS中,它看起来像这样:
<audio id="audio-tag" controls="controls" preload="none"> //need the ID to get element
<source type="audio/mpeg" src="{{selectedSongPath}}"/>
</audio>
....
$scope.selectedSongPath = songPath; //you're changing the src
document.getElementById("audio-tag").load(); //here you load the file (you need equivalent in your framework)
希望它有所帮助。
答案 10 :(得分:0)
我之前使用的是ngAudio&amp;面对多个音频一次播放的问题。当试图使用HTML5音频标签时,而不是使用音频和音频。 source为2个标签,只有1个标签解决了我的问题。
<audio controls ng-src='{{trusted_url }}'></audio>