最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Can I use Angular variables as the source of an audio tag? - Stack Overflow

programmeradmin4浏览0评论

I am trying to do the following:

<div ng-repeat="audio in event.audios">
    <audio ng-src="/data/media/{{audio}}" controls></audio>
</div>

But when I load the view, the {{audio}} variable is not parsed but hardcoded into the source as is. However, if for example, I place that same variable outside of the audio tag it renders the name of the audio file correctly. I've tried using both src and ng-src to no avail.

Is there a way to get the variable to work within an audio tag?

Thanks in advance.

I am trying to do the following:

<div ng-repeat="audio in event.audios">
    <audio ng-src="/data/media/{{audio}}" controls></audio>
</div>

But when I load the view, the {{audio}} variable is not parsed but hardcoded into the source as is. However, if for example, I place that same variable outside of the audio tag it renders the name of the audio file correctly. I've tried using both src and ng-src to no avail.

Is there a way to get the variable to work within an audio tag?

Thanks in advance.

Share Improve this question asked May 14, 2014 at 15:47 HolsHols 3911 gold badge5 silver badges22 bronze badges 1
  • 1 Think this is a different case, in the link you posted the variable he is using renders fine but the video doesn't plays. In my case the variable is not being parsed. I am also using it within an ng-repeat. – Hols Commented May 14, 2014 at 16:14
Add a comment  | 

4 Answers 4

Reset to default 7

I'm not all that familiar with the ngSrc directive outside of using it on images, but it might require an img tag somewhere in the source.

Try this:

<div ng-repeat="audio in event.audios">
    <audio ng-attr-src="/data/media/{{audio}}" controls></audio>
</div>

The ng-attr- directive can be used for any attribute that doesn't have a specific role in angular. You can read more about it on this page.

Update, I was wrong.

I created a jsfiddle and found the actual error that was occurring.

You're getting an error from the sce service. See the SO question here.

The solution is to use $sce.trustAsResourceUrl().

Example:

angular.module('AudioTest', [])
.controller('AudioTestCtrl', function($scope, $sce) {
    $scope.event = { 'audios': [
        $sce.trustAsResourceUrl('/data/media/test1'),
        $sce.trustAsResourceUrl('/data/media/test2')
    ]};
});

Here's the fiddle.

Update #2

If you don't want to set the url as hard coded or loop through after you get a response from the server, you can use a custom filter to accomplish what you're looking for. This method does not use interpolation, which is where the error is being thrown.

JS:

angular.module('AudioTest', [])
.filter('trustedAudioUrl', function($sce) {
    return function(path, audioFile) {
        return $sce.trustAsResourceUrl(path + audioFile);
    };
})
.controller('AudioTestCtrl', function($scope) {
    $scope.event = { 'audios': ['test1', 'test2']};
});

HTML:

<div ng-app="AudioTest">
    <div ng-controller="AudioTestCtrl">
        <div ng-repeat="audio in event.audios">
            <audio ng-src="/data/media/ | trustedAudioUrl:audio)" controls></audio>
        </div>
    </div>
</div>

And the new fiddle.

Ok, thanks to theJoeBiz's input and some thinking around I solved this by making a directive, here is the code:

app.directive('audios', function($sce) {
  return {
    restrict: 'A',
    scope: { code:'=' },
    replace: true,
    template: '<audio ng-src="{{url}}" controls></audio>',
    link: function (scope) {
        scope.$watch('code', function (newVal, oldVal) {
           if (newVal !== undefined) {
               scope.url = $sce.trustAsResourceUrl("/data/media/" + newVal);
           }
        });
    }
  };
});

Then on the template I used it like so:

<div ng-repeat="audio in event.audios">
    <div audios code="audio"></div>
</div>

It is all working fine now.

Hey FWIW i found this page looking for a solution to template URL's for my audio tag. However I am using multiple source tags for cross browser support:

<audio id="myAudioTag">
  <source ng-src="{{sceSoundUrlMp3}}">
  <source ng-src="{{sceSoundUrlOgg}}">
</audio>

First I solved SCE issues by whitelisting *.ogg, *.mp3: (keep 'self' otherwise your future requests fail)

.config(function($sceDelegateProvider) {
  $sceDelegateProvider.resourceUrlWhitelist([
    "self",
    /(mp3|ogg)$/,
  ]);
})

This stopped giving SCE errors but Firefox reported 'no source' and didn't notice the src tag angular added.

The last step was to call load on the element after trusting and setting $scope.sceSoundUrlMp3: $('#myAudioTag')[0].load()

I have used $sce.trustAsResourceUrl("/data/media/" + newVal) but it didn't work.What seemed to work for me was to put document.getElementById('player').src = {{url}} in the controller

Hope that helps someone else.

发布评论

评论列表(0)

  1. 暂无评论