Подтвердить что ты не робот

Изменение атрибута "src" источника html5 не влияет на угловые

У меня есть список аудиофайлов, представленных в виде ссылок и <audio> html5. Каждая ссылка вызывает функцию, которая меняет src тега <source> в <audio>:

<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 одним из путей, плеер работает.

Что я делаю неправильно?

4b9b3361

Ответ 1

Вот пара подходов angular:

1) Используйте ng-src= вместо src=

Документы angular объясняют, почему это работает: http://docs.angularjs.org/api/ng.directive:ngSrc

На этапе компиляции angular расширит элемент, включив в него правильный атрибут src=.

Это изменит атрибут src для аудио-элемента HTML5, но, к сожалению, этого недостаточно для создания новой песни. Вам нужно подтолкнуть аудио-элемент к тому, чтобы сделать что-то, вызвав метод .play().

Отстой: (

Дальнейший взлом по этому же пути предполагает использование DOM-манипуляции внутри контроллера. Это, как правило, признак того, что это неправильное решение.

Лучшее решение - использовать службы!!!

2) Аудио с помощью службы angular

// 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 !
    }
}

Теперь вы можете добавить "звук" в качестве параметра к любому из ваших контроллеров, которые должны иметь возможность изменить музыку и использовать тот же самый вызов API, определенный здесь.

Будучи "службой", для всего приложения существует только один экземпляр. Все вызовы на "звук" указывают на один и тот же объект. Это справедливо для всех служб в angular. Только то, что нам нужно в этом случае.

Служба создает невидимый элемент HTML5 в корневом документе вашего приложения, поэтому нет необходимости добавлять тег в свои представления в любом месте. Это добавляет бонус к сохранению воспроизведения песни, пока пользователь переходит к различным представлениям.

См. http://docs.angularjs.org/api/ng. $document для определения службы $document.

Надеюсь, что поможет спарить:)

Ответ 2

У меня была та же проблема, даже после использования $sce.trustAsResourceUrl, а затем я понял, что проблема связана с HTML. Источник должен войти в сам тег аудио:

<audio controls data-ng-src="{{yourTrustedUrl}}" ></audio>

Ответ 3

<audio ng-src="{{getAudioUrl()}}" audioplayer controls></audio>

$scope.getAudioUrl = function() {
return $sce.trustAsResourceUrl('your url');
};

Это работает для меня, вам нужно обезопасить вас.

Ответ 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");
   };

замените мой URL следующим образом:

$sce.trustAsResourceUrl('your Url');

Не забудьте добавить $sce в свой модуль:

angular.module('myApp.controllers', [])
  .controller('MyCtrl1',  function($scope,$http,$routeParams,$sce) {

Ответ 5

У меня была аналогичная проблема с загрузкой источников видео в меню выпадающего меню. Я обнаружил, что $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; увы, я не могу найти ссылку, где я узнал этот трюк. Если я это сделаю, я отправлю его в качестве комментария к этому ответу.

Надеюсь, что это поможет:)

Ответ 6

Вы также можете использовать это:

<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 тоже ограничительный и когда вы абсолютно доверяете источнику контента вы привязываетесь к.

далее здесь

Ответ 7

Подход

@SteveOC 64 связан с созданием нового экземпляра Audio. Если у вас уже есть тег Audio, например

<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 factory вы можете называть его как

 audio.play('/api/resource?resource=' + uri);

если это событие управляется, как в звуке воспроизведения при нажатии другого элемента

$scope.$apply(function() {
   $scope.audioPlayer = true;
   audio.play('/api/resource?resource=' + uri);
   $scope.isAudioPlaying = true;
});

И если кто-то ищет видео factory:

HTML

<video id="video" controls></video>

Factory

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);

Надеюсь, это поможет!

Ответ 8

Решение, которое я нашел, - загрузить видео, как только вы получите URL-адрес видео от вызова ajax.

var video = angular.element('#video_id');
video.load();

Ответ 9

Никогда не пробовался с тегом audio, но src должен быть интерполирован, поэтому он должен быть между {{}}.

<audio controls="controls" preload="none">
  <source type="audio/mpeg" src="{{selectedSongPath}}"/>
</audio>

Вы уже пробовали это?

Ответ 10

После изменения 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)

Надеюсь, что это поможет.

Ответ 11

Раньше я использовал ngAudio и сталкивался с проблемой одновременного воспроизведения нескольких аудиофайлов. Когда вы пытались использовать аудиотекст HTML5, вместо того, чтобы иметь аудио и источник как 2 тега, только 1 тег решил мою проблему.

<audio controls ng-src='{{trusted_url }}'></audio>