angularjs - sobre - pasar el mouse html
Cambiar el atributo de fuente "src" de html5 no tiene efecto con angularjs (11)
Tengo una lista de archivos de audio presentados como enlaces y un <audio>
html5. Cada enlace invoca una función que cambia el src de la etiqueta <source>
dentro del <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;
}
Puedo ver el cambio de fuente, pero no se toca nada. Los caminos están bien; Si inicializo el src con una de las rutas, el reproductor funciona.
¿Qué estoy haciendo mal?
Aquí hay un par de enfoques angulares:
1) Use ng-src = en lugar de src =
Los documentos angulares explican por qué funciona esto: http://docs.angularjs.org/api/ng.directive:ngSrc
Durante la etapa de compilación, angular expandirá el elemento para incluir el atributo src = correcto.
Esto cambiará el atributo src del elemento de audio HTML5, pero desafortunadamente eso NO es suficiente para hacer que se reproduzca una nueva canción. Necesita hacer que el elemento de audio haga algo llamando al método .play ().
Chupa :(
Más piratería a lo largo de este mismo camino sugiere hacer manipulación de DOM dentro del controlador. Esto es generalmente una señal de que esta es la solución incorrecta.
¡Mejor solución es usar servicios!
2) Audio utilizando un servicio 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.
}
});
Ahora, en su (s) controlador (es), puede inyectar ''audio'' y hacer lo que sea necesario para hacerlo.
p.ej:
function myAstoundingAudioCtrl($scope, audio) { //<-- NOTE injected audio service
$scope.songSelect = function(songPath) {
audio.play(songPath); // <--- Thats All You Need !
}
}
Ahora puede agregar ''audio'' como parámetro a cualquiera de sus controladores que necesitan poder cambiar la música, y usar la misma llamada API definida aquí.
Al ser un ''servicio'', solo hay una instancia para toda la aplicación. Todas las llamadas a ''audio'' apuntan al mismo objeto. Esto es cierto para todos los servicios en angular. Justo lo que necesitamos en este caso.
El servicio crea un elemento HTML5 invisible en el documento raíz de su aplicación, por lo que no es necesario agregar una etiqueta a sus vistas en ningún lugar. Esto tiene la ventaja adicional de mantener la reproducción de la canción mientras el usuario navega a diferentes vistas.
Consulte http://docs.angularjs.org/api/ng . $ Document para ver la definición del servicio $ document.
Espero que ayude a mate :)
Después de cambiar el src, también tiene que cargar ese archivo, así que intente agregar a su función songselect
después de $scope.selectedSongPath = songPath;
el seguimiento:
$scope.load();
No sé cuál es el alcance de $ en su caso, pero el método load()
debe ejecutarse dentro del objeto de su etiqueta de audio. En JS simple se vería así:
<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)
Espero eso ayude.
El enfoque de @SteveOC 64 trata sobre la creación de una nueva instancia del audio. Si ya tienes una etiqueta de audio como
<audio id="audio" controls></audio>
Puedes probar el siguiente código
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://.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)
};
},
}
});
Y en su controlador después de inyectar audio
fábrica de audio
, puede llamarlo como
audio.play(''/api/resource?resource='' + uri);
Si se trata de un evento controlado, como reproducir audio al hacer clic en otro elemento
$scope.$apply(function() {
$scope.audioPlayer = true;
audio.play(''/api/resource?resource='' + uri);
$scope.isAudioPlaying = true;
});
Y si alguien está buscando la fábrica de videos:
HTML
<video id="video" controls></video>
Fábrica
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://.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)
};
},
}
});
Y puedes invocarlo como video.play(''/api/resource?resource='' + uri);
¡Espero que esto ayude!
Estuve usando ngAudio anteriormente y enfrenté el problema de múltiples audios reproducidos a la vez. Cuando intenté usar la etiqueta de audio HTML5, en lugar de tener audio y fuente como 2 etiquetas, solo 1 etiqueta resolvió mi problema.
<audio controls ng-src=''{{trusted_url }}''></audio>
La solución que encontré es cargar el video en cuanto recibas la url del video de ajax call.
var video = angular.element(''#video_id'');
video.load();
Nunca intente con audio
etiqueta de audio
, pero src
debe interpolarse, por lo que debe estar entre {{}}
.
<audio controls="controls" preload="none">
<source type="audio/mpeg" src="{{selectedSongPath}}"/>
</audio>
¿Ya has probado esto?
También puedes usar esto:
<div ng-bind-html-unsafe="audioPlayer"></div>
En su controlador:
$scope.audioPlayer="<br /><audio controls><source src=/""+ audiosource + "/" type=/"audio/mpeg/"> Your browser does not support the audio element. </audio>"
Atención:
Debe usar esta directiva solo si la directiva ngBindHtml es demasiado restrictiva y cuando confía absolutamente en la fuente del contenido al que está vinculado.
más aquí
Tuve el mismo problema, incluso después de usar $ sce.trustAsResourceUrl, y luego me di cuenta de que el problema es con el HTML. La fuente debe ir en la propia etiqueta de audio:
<audio controls data-ng-src="{{yourTrustedUrl}}" ></audio>
Tuve un problema similar al cargar fuentes de video con un menú de selección desplegable. Encontré que $scope.$apply();
era todo lo que necesitaba para agregar. No he tenido tiempo de tomar su código y probar esta implementación, pero recomiendo probar esto:
$scope.songSelect = function(songPath) {
$scope.selectedSongPath = songPath;
$scope.$apply();
}
Existe alguna disputa sobre el uso de $scope.$apply()
respecto a los errores de manejo. Creo que la implementación correcta es en realidad como sigue:
$scope.songSelect = function(songPath) {
$scope.$apply(function() {
$scope.selectedSongPath = songPath;
});
}
Esto supuestamente se hace mejor si songPath
devuelve indefinido; Lamentablemente no puedo encontrar el enlace donde aprendí este truco. Si lo hago, lo publicaré como un comentario a esta respuesta.
Espero que esto ayude :)
ngSrc no funciona para video en AngularJS, solo funciona para imagen. Mi solución es:
en la vista:
<video controls="controls" name="Video Name" ng-src="{{getVideoUrl()}}"></video>
en el controlador:
$scope.getVideoUrl=function(){
return $sce.trustAsResourceUrl("media/"+$scope.groupedProjList[$scope.routeId].CONTACTNAME+".mp4");
};
Reemplaza mi Url con el tuyo:
$sce.trustAsResourceUrl(''your Url'');
No olvides agregar $sce
a tu módulo:
angular.module(''myApp.controllers'', [])
.controller(''MyCtrl1'', function($scope,$http,$routeParams,$sce) {
<audio ng-src="{{getAudioUrl()}}" audioplayer controls></audio>
$scope.getAudioUrl = function() {
return $sce.trustAsResourceUrl(''your url'');
};
Esto está funcionando para mí, necesitas santificarte.