Cómo obtener la duración de Audio Stream y continuar la transmisión de audio desde cualquier punto
Descripción:
Tengo código siguiente para un jugador audio. Puedo continuar la reproducción de audio desde cualquier duración haciendo clic en la barra de progreso (entre 0 a mediaplayer.getDuration ()). Funciona perfectamente para la reproducción de audio.
- Silenciar un video en un VideoView
- Reproducir stream de RTMP de audio en android
- Necesita Android equivalente de AudioInputStream
- Transmisión de audio a través de socket TCP en Android
- ¿Qué debo usar aparte del paquete `javax.net.sampled` para manejar la transmisión de audio?
Problema en la transmisión de audio:
- Cuando transmito un archivo de audio desde un servidor de Internet (digamos s3-bucket), comienza a transmitir correctamente.
- Pero mediaPlayer.getDuration () y mediaPlayer.getCurrentPosition () devuelven valores erróneos. Al principio de la transmisión mediaPlayer.getCurrentPosition () devuelve 5 horas.
- Debido a esto no puedo continuar la transmisión de Audio desde una duración especificada de Stream (Duración de 0 a Stream).
Preguntas:
- ¿Cómo puedo obtener la duración de un flujo de audio
- ¿Cómo puedo continuar Streaming de audio desde una duración especificada. Por ejemplo, para un archivo de 10 minutos de duración, quiero iniciar la transmisión a partir del minuto 6.
Código:
public class MyAudioPlayer extends Activity implements OnClickListener{ MediaPlayer mediaPlayer = null; private boolean isPaused=false; private boolean isStop = true; String filePath = null; String productName = null; ImageButton btnPlay = null; ImageButton btnPause = null; ImageButton btnReset = null; ImageButton btnStop = null; AudioManager audioManager = null; SeekBar volControl = null; SeekBar progressControl = null; TextView progressText = null; long durationInMillis = -1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.ltd_audio_player); volControl = (SeekBar)findViewById(R.id.player_volume); progressControl = (SeekBar)findViewById(R.id.player_seekbar); progressText = (TextView) findViewById(R.id.player_progress_text); btnPlay = (ImageButton) findViewById(R.id.ic_player_play); btnPause = (ImageButton) findViewById(R.id.ic_player_pause); btnReset = (ImageButton) findViewById(R.id.ic_player_reset); btnStop = (ImageButton) findViewById(R.id.ic_player_stop); btnPlay.setOnClickListener(this); btnPause.setOnClickListener(this); btnReset.setOnClickListener(this); btnStop.setOnClickListener(this); filePath = getIntent().getExtras().getString("localPath"); this.setPlayer(); this.resetAndStartPlayer(); } @Override protected void onResume() { super.onResume(); isPaused=false; progressText.postDelayed(onEverySecond, 1000); } @Override protected void onPause() { super.onPause(); isPaused=true; } private void setProgressControl() { int maxVolume = mediaPlayer.getDuration(); int curVolume = mediaPlayer.getCurrentPosition(); progressControl.setMax(maxVolume); progressControl.setProgress(curVolume); progressControl.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) { mediaPlayer.seekTo(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } @Override public void onStopTrackingTouch(SeekBar seekBar) { // TODO Auto-generated method stub } }); } @Override public void onClick(View v) { switch(v.getId()){ case R.id.ic_player_play: if(isStop==true){ try { mediaPlayer.prepareAsync(); } catch (Exception e) { e.printStackTrace(); } }else{ mediaPlayer.start(); isStop = true; } break; case R.id.ic_player_pause: mediaPlayer.pause(); break; case R.id.ic_player_reset: mediaPlayer.seekTo(0); break; case R.id.ic_player_stop: isStop = true; progressControl.setProgress(0); mediaPlayer.stop(); break; } } private void resetAndStartPlayer(){ try { if(filePath!=null){ mediaPlayer.setDataSource(filePath); mediaPlayer.prepareAsync(); } } catch (Exception e) { e.printStackTrace(); } } private void setPlayer(){ getWindow().setFormat(PixelFormat.UNKNOWN); mediaPlayer = new MediaPlayer(); mediaPlayer.setOnBufferingUpdateListener(new OnBufferingUpdateListener() { @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { progressControl.setSecondaryProgress((progressControl.getMax()/100)*percent); } }); mediaPlayer.setOnPreparedListener(new OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mediaPlayer.start(); isStop=false; durationInMillis = mediaPlayer.getDuration(); MyAudioPlayer.this.setProgressControl(); } }); mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); } @Override protected void onDestroy() { // TODO Auto-generated method stub mediaPlayer.release(); super.onDestroy(); } protected void setProgressText() { durationInMillis = mediaPlayer.getDuration(); int curVolume = mediaPlayer.getCurrentPosition(); long HOUR = 60*60*1000; if(progressText!=null){ if(durationInMillis>HOUR){ progressText.setText(String.format("%1$tH:%1$tM:%1$tS", new Date(curVolume)) +" / "+String.format("%1$tH:%1$tM:%1$tS", new Date(durationInMillis))); }else{ progressText.setText(String.format("%1$tM:%1$tS", new Date(curVolume)) +" / "+String.format("%1$tM:%1$tS", new Date(durationInMillis))); } } } private Runnable onEverySecond=new Runnable() { public void run() { if (mediaPlayer!=null) { progressControl.setProgress(mediaPlayer.getCurrentPosition()); MyAudioPlayer.this.setProgressText(); } if (!isPaused) { progressText.postDelayed(onEverySecond, 1000); } } }; }
La hora se muestra por encima de la barra de progreso.
Tiempo: 'Duración actual' / 'Duración total'
- Uso de Fluidsynth para reproducir notas de SoundFonts en Android
- Transmisión de audio a un dispositivo a través de MediaRouter
- Flujo de audio Bluetooth entre dispositivos Android
- Difusión de audio / vídeo desde android vía udp a wifi y escuchar con vlc
- JPlayer detiene en el centro de la pista y comienza a repetir una sección de la pista
- Enviar un audio de multidifusión en rtsp mediante el uso de libstreaming para la transferencia de un dispositivo android
- ¿Por qué toma tanto tiempo para que MediaPlayer de Android prepare algunas secuencias en vivo para su reproducción?
- Transmisión de audio MP3 mediante comunicación de socket mediante OpenSL ES en Android
Espero que pueda resolver su problema.
1) Duración y progreso de la transmisión de audio
He mirado en su código, usted tiene un error importante en su código para calcular el tiempo. Crea nueva fecha (durationInMillis). La fecha agrega su locallity es decir GMT + XX horas, que es porqué usted está consiguiendo 5 horas en el principio de fluir. Debe utilizar el siguiente método para calcular currentProgress / duration.
protected void setProgressText() { final int HOUR = 60*60*1000; final int MINUTE = 60*1000; final int SECOND = 1000; int durationInMillis = mediaPlayer.getDuration(); int curVolume = mediaPlayer.getCurrentPosition(); int durationHour = durationInMillis/HOUR; int durationMint = (durationInMillis%HOUR)/MINUTE; int durationSec = (durationInMillis%MINUTE)/SECOND; int currentHour = curVolume/HOUR; int currentMint = (curVolume%HOUR)/MINUTE; int currentSec = (curVolume%MINUTE)/SECOND; if(durationHour>0){ System.out.println(" 1 = "+String.format("%02d:%02d:%02d/%02d:%02d:%02d", currentHour,currentMint,currentSec, durationHour,durationMint,durationSec)); }else{ System.out.println(" 1 = "+String.format("%02d:%02d/%02d:%02d", currentMint,currentSec, durationMint,durationSec)); } }
2) Fregado para la corriente.
MediaPlayer permite el lavado de la corriente de audio. Lo he implementado en uno de mis proyectos, pero lleva algún tiempo. Lleva algún tiempo reanudar la transmisión de audio desde otra ubicación.
El primer gran problema es tu orden de inicialización: llamas a getDuration antes de llamar a setDataSource en resetAndStartPlayer. ¿Cómo se supone que MediaPlayer conozca la duración sin fuente de datos?
A continuación, le indicamos cómo hacerlo correctamente:
-
Llame a MediaPlayer.setDataSource () en Activity.onCreate
-
Ejecutar AsyncTask, en su llamada doInBackground MediaPlayer.prepare (), esto tomará un tiempo si es streaming de http, pero después de que termine, el jugador debe saber la longitud de los medios de comunicación
- En la llamada AsyncTask.onPostExecute MediaPlayer.getDuration (), que debería tener éxito si la secuencia se abrió correctamente; Después puede llamar a MediaPlayer.start ()
Cosas importantes:
- GetDuration funciona después de prepararse se llamó
- Preparar puede tomar más tiempo, y debe ser llamado en otro hilo
- También puede utilizar prepareAsync y evitar AsyncTask, a continuación, utilizar la devolución de llamada setOnPreparedListener para llamar a getDuration
- ¿Qué intenciones tiene la aplicación de Facebook para Android?
- Color de fondo de Android LinearLayout Selector