TransWikia.com

Como evaluar si un audio se esta reproduciendo

Stack Overflow en español Asked by Pancho Bolatti on January 23, 2021

Buenas estoy haciendo un reproductor de audio con angular js. Pude lograr que el botón reciba la URL del audio y ejecutar ese audio mediante una función, pero estoy teniendo problemas para hacer que ese audio se pause cuando presione el botón y se reanude desde el punto donde lo deje.

var app = angular.module('audioApp',[])

app.controller('audioController',function($scope){
    // texto botón reproducir
    $scope.playText = "Reproducir";

    // imagen botón reproducir
    $scope.pauseBtn = 'img/ic_reproductor_play_normal.png';

    // función para cambiar la imagen y el texto del boton
    $scope.changeImg = function() {
        if($scope.playText == 'Reproducir') {

            // sí el playText dice "Reproducir" cambiamos a "Pausar"
            $scope.playText = "Pausar";
            $scope.pauseBtn = 'img/ic_reproductor_pausa_normal.png';


            playAudio();

        } else if($scope.playText == 'Pausar') {

            // sí el playText dice "Pausar" cambiamos a "Reproducir"
            $scope.playText = "Reproducir";
            $scope.pauseBtn = 'img/ic_reproductor_play_normal.png';



        }
    }


    //Función para reproducir un audio

    function playAudio(){

        var req = 'https://api.twilio.com/2010-04-01/Accounts/ACc86242677f1f69823986da845f65eb27/Messages/MMa5d0dc372fd919c57048757f49ddb383/Media/ME8f416923ff48c0d2ab850602b8d165b4';

        var audio = new Audio(req);

        audio.play();


    }


    })
.receptor{
    font: 110% Roboto;
    font-weight: 400;
    color: #f4f4f4;
    background: #f1f1f1;
    width: 100%;
}


.boton_reproducir{
    display:inline-flex;
    justify-content: center;
    align-items: center;
    font: 90% Roboto;
    font-weight: 500;
    border: transparent;
    width: 100%;
    cursor: pointer;
}



.div-boton-reproducir{
    width: 9rem;
}
<!DOCTYPE html>
<html ng-app="audioApp">
<head>
    <meta charset="UTF-8">
    <title>Audio Angular</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.32/angular.min.js"></script>
    <script src="app.js"></script>
    <link rel="stylesheet" href="estilos.css"/>
</head>
<body>

    <div ng-controller="audioController">
        <div class="div-boton-reproducir">
            <div class="receptor">
                <button class="boton_reproducir" ng-click="changeImg()">
                    <img ng-src="{{pauseBtn}}"/>
                    <b>{{playText}}</b>
                </button>
            </div>
        </div>
    </div>




</body>
</html>

One Answer

Espero que te valga esta respuesta. He tratado de comentar en el código la mayoría de cosas y detalles, así que espero que queden todos los cambios más o menos claros.

Los puntos importanes y documentación:

  • El elemento AUDIO DE HTML Importante que lo revises.
  • He separado la función de carga del audio para que sea independiente del play. Uno de los problemas era que lo recargabas continuamente al dar a play, pues volvías a crear el objeto.
  • He aislado la función de cambiar texto de los botones y la de play o pause. De este modo, la capa de presentación y lógica están algo más separadas. Te he dejado notas al respecto en el código.
  • He añadido iconos que se veían, y los he controlado con un ng-íf (en el código encontrarás enlaces a la documentación), mucho más cómodo si utilizas angularjs que hacerlo en modo "Jquery" que era un poco lo que hacías.
  • llamo al método pause o play del Audio en función de las propiedades del objeto audio. De este modo no tengo que crear if extraños, ni controles, si no que accedo a sus propiedades y sé si se está reproduciendo o no.

Creo que no me dejo nada. Si ves que pueda faltar algo coméntame!!

Un saludo

var app = angular.module('audioApp', [])

app.controller('audioController', function($scope) {
  // texto botón reproducir
  $scope.playText = "Reproducir";
  //AÑADO AQUÍ EL AUDIO PARA QUE SEA ACCESIBLE POR TODAS LAS FUNCIONES


  var req = 'https://api.twilio.com/2010-04-01/Accounts/ACc86242677f1f69823986da845f65eb27/Messages/MMa5d0dc372fd919c57048757f49ddb383/Media/ME8f416923ff48c0d2ab850602b8d165b4';


  //Inicio un audio para todo el controller

  $scope.audio = new Audio();

  //Este audio puedes cargarlo después con un parámetro cuando quieras
  loadAudio(req);

  // imagen botón reproducir
  $scope.pauseBtn = 'img/ic_reproductor_play_normal.png';

  // función para cambiar la imagen y el texto del boton
  // Como verás, lo que he hecho es separar la función de changeImg y quitarle la llamada a la reproducción. Es un error asignar esa funcionalidad dentro del cambio de imagen, ya que estás ligando la funcionalidad a la presentación, y debería ser al contrario. Yo he creado una función "playAudio" que cuando se ejecuta, llama a la función changeImg, siendo esta la encargada de decidir si debe pintar una u otra cosa. 

  $scope.changeImg = function() {
    //Puedes acceder a las propiedades del objeto audio estándares https://www.w3schools.com/jsref/prop_audio_src.asp para saber si está pausado o no

    if (!$scope.audio.paused) {
      //Sí el playText dice "Reproducir" cambiamos a "Pausar"
      $scope.playText = "Pausar";

    } else if ($scope.audio.paused) {
      // sí el playText dice "Pausar" cambiamos a "Reproducir"
      $scope.playText = "Reproducir";
    }
  }


  //Esta función podrías llamarla después de obtener cualquier url a tu gusto. Únicamente asocia esa URL al audio

  function loadAudio(reqUrl) {
    $scope.audio.src = reqUrl;
  }

  //Función para reproducir un audio. 
  //En este caso, si observas, llamo a los métodos pause o play en función de las variables propias del objeto de HTML Audio.
  $scope.playAudio = function() {
    if ($scope.audio.paused) {
      $scope.audio.play();
    } else {
      $scope.audio.pause();
    }
    //Además, llamo al método de cambiar la imagen.
    $scope.changeImg();
  }




})
.receptor {
  font: 110% Roboto;
  font-weight: 400;
  color: #f4f4f4;
  background: #f1f1f1;
  width: 100%;
}

.boton_reproducir {
  display: inline-flex;
  justify-content: center;
  align-items: center;
  font: 90% Roboto;
  font-weight: 500;
  border: transparent;
  width: 100%;
  cursor: pointer;
}

.div-boton-reproducir {
  width: 9rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html ng-app="audioApp">

<head>
  <meta charset="UTF-8">
  <title>Audio Angular</title>
  <script src="app.js"></script>
  <link rel="stylesheet" href="estilos.css" />
</head>
<body>
  <h3>Espero que el ejemplo te valga. Creo que es completamente funcional.</h3>
  <p><i>Verás que he añadido también el botón pause o play como <a href="https://icons.getbootstrap.com" target="_blank">iconos</a>, y con <a href="https://docs.angularjs.org/api/ng/directive/ngIf" target="_blank">ng-if</a> controlo fácilmente que aparezca uno u otro</i></p>

  <div ng-controller="audioController">
    <div class="div-boton-reproducir">
      <div class="receptor">
        <button class="boton_reproducir" ng-click="playAudio()">
                    
                    <b>{{playText}}</b>
                    <svg ng-if="!audio.paused"  width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-pause-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
  <path d="M5.5 3.5A1.5 1.5 0 0 1 7 5v6a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 1.5-1.5zm5 0A1.5 1.5 0 0 1 12 5v6a1.5 1.5 0 0 1-3 0V5a1.5 1.5 0 0 1 1.5-1.5z"/>
</svg>
<svg ng-if="audio.paused" width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-play-fill" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
  <path d="M11.596 8.697l-6.363 3.692c-.54.313-1.233-.066-1.233-.697V4.308c0-.63.692-1.01 1.233-.696l6.363 3.692a.802.802 0 0 1 0 1.393z"/>
</svg>
                </button>
      </div>
    </div>
  </div>
</body>

</html>

Correct answer by Alejandro Teixeira Muñoz on January 23, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP