#android #audio-streaming #audio-player
#Android #потоковое аудио #Аудиоплеер
Вопрос:
Мне нужно воспроизвести аудиофайл с удаленного сервера в моем приложении. Я мог воспроизводить, когда тестировал с localhost server (используя WAMP). Когда тот же файл предоставлен с сервера, он не работает.. Файл не имеет расширения, а содержимое — MP3
String fileUrl = "http://192.168.1.131/myproject/songs/xyz";
String url = "http://myserver/songs/xyz"; //(myserver -> A remote server)
mVideoView.setVideoURI(Uri.parse(fileUrl));
mVideoView.requestFocus();
Также мне нужно лучше контролировать проигрыватель.
Пожалуйста, помогите…
Ответ №1:
public void onRadioClick(View v) {
if (!isPLAYING) {
isPLAYING = true;
MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource(getString(R.string.audio_stream));
mp.prepare();
mp.start();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
}
} else {
isPLAYING = false;
stopPlaying();
}
}
private void stopPlaying() {
mp.release();
mp = null;
}
Ответ №2:
Приведенный выше ответ обеспечивает синхронную выборку и воспроизведение, что означает, что текущий выполняющийся поток будет заблокирован до завершения prepare().
Вместо этого можно использовать prepareAsync() для асинхронной «подготовки» потока. Вам также потребуется обработать событие onPrepared (), чтобы начать воспроизведение.
mediaPlayer.setDataSource(URL here);
mediaPlayer.prepareAsync();
Добавить готовый обработчик событий:
mPlayer.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
mPlayer.start();
}
});
Тем не менее, по-видимому, нет способа настроить размер буфера потоковой передачи. Разочарование…
Комментарии:
1. Для настройки размера буфера потоковой передачи в пользовательских блоках Google рекомендует использовать свой ExoPlayer . Это то, что приложение YouTube использует прямо сейчас и работает для потоковой передачи mp3.
2. Если вы хотите воспроизводить только аудио, тогда вам следует использовать MediaPlayer, потому что ExoPlayer потребляет больше заряда батареи, чем MediaPlayer.
Ответ №3:
> import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageButton;
import android.widget.SeekBar;
import com.google.ads.Ad;
import com.google.ads.AdListener;
import com.google.ads.AdRequest;
import com.google.ads.AdRequest.ErrorCode;
import com.google.ads.InterstitialAd;
/**
* @author Rashid Ali
* @Date Sep 18, 2014
* @Email <rashid.android.developer@gmail.com>
*
*/
public class AudioPlayerActivity extends Activity implements OnClickListener,
OnTouchListener, OnCompletionListener, OnBufferingUpdateListener,
AdListener {
private ProgressDialog progressBar;
private static final String AD_UNIT_ID_GOES_HERE = "ca-app-pub-5453344383403527/5064575693";
private InterstitialAd interstitialAd;
private ImageButton buttonPlayPause;
private SeekBar seekBarProgress;
private MediaPlayer mediaPlayer;
private int mediaFileLengthInMilliseconds; // this value contains the song
// duration in milliseconds.
// Look at getDuration() method
// in MediaPlayer class
private final Handler handler = new Handler();
String audioName;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_audio_player);
interstitialAd = new InterstitialAd(this, AD_UNIT_ID_GOES_HERE);
interstitialAd.setAdListener(this);
AdRequest adRequest = new AdRequest();
adRequest.addTestDevice(AdRequest.TEST_EMULATOR);
interstitialAd.loadAd(adRequest);
initilizeUI();
Intent intent = getIntent();
audioName = intent.getStringExtra("audioName");
}
/** This method is used to Initialize UI Components. */
private void initilizeUI() {
buttonPlayPause = (ImageButton) findViewById(R.id.ButtonTestPlayPause);
buttonPlayPause.setOnClickListener(this);
seekBarProgress = (SeekBar) findViewById(R.id.SeekBarTestPlay);
seekBarProgress.setMax(99);
seekBarProgress.setOnTouchListener(this);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
/**
* Method which updates the SeekBar primary progress by current song playing
* position
*/
private void primarySeekBarProgressUpdater() {
seekBarProgress.setProgress((int) (((float) mediaPlayer
.getCurrentPosition() / mediaFileLengthInMilliseconds) * 100)); // This
// math
// construction
// give
// a
// percentage
// of
// "was playing"/"song length"
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification, 1000);
}
}
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
/**
* Method which updates the SeekBar secondary progress by current song
* loading from URL position
*/
seekBarProgress.setSecondaryProgress(percent);
}
@Override
public void onCompletion(MediaPlayer mp) {
/**
* MediaPlayer onCompletion event handler. Method which calls then song
* playing is complete
*/
// buttonPlayPause.setImageResource(R.drawable.button_play);
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (v.getId() == R.id.SeekBarTestPlay) {
/**
* Seekbar onTouch event handler. Method which seeks MediaPlayer to
* seekBar primary progress position
*/
if (mediaPlayer.isPlaying()) {
SeekBar sb = (SeekBar) v;
int playPositionInMillisecconds = (mediaFileLengthInMilliseconds / 100)
* sb.getProgress();
mediaPlayer.seekTo(playPositionInMillisecconds);
}
}
return false;
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.ButtonTestPlayPause) {
/**
* ImageButton onClick event handler. Method which start/pause
* mediaplayer playing
*/
try {
mediaPlayer.setDataSource(audioName); // setup
// song
// from
// http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3
// URL
// to
// mediaplayer
// data
// source
mediaPlayer.prepare(); // you must call this method after setup
// the datasource in setDataSource
// method. After calling prepare() the
// instance of MediaPlayer starts load
// data from URL to internal buffer.
} catch (Exception e) {
e.printStackTrace();
}
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets
// the
// song
// length
// in
// milliseconds
// from
// URL
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
buttonPlayPause.setImageResource(R.drawable.pause_button);
} else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.play_button);
}
primarySeekBarProgressUpdater();
}
}
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
mediaPlayer.stop();
this.finish();
}
@Override
public void onDismissScreen(Ad arg0) {
// TODO Auto-generated method stub
}
@Override
public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) {
// TODO Auto-generated method stub
}
@Override
public void onLeaveApplication(Ad arg0) {
// TODO Auto-generated method stub
}
@Override
public void onPresentScreen(Ad arg0) {
// TODO Auto-generated method stub
}
@Override
public void onReceiveAd(Ad ad) {
// TODO Auto-generated method stub
if (ad == interstitialAd) {
interstitialAd.show();
}
}
}
<RelativeLayout
android:id="@ id/layout_header"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@drawable/header" >
</RelativeLayout>
<RelativeLayout
android:id="@ id/ad_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_below="@ id/layout_header" >
<com.google.ads.AdView
android:id="@ id/googleads"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
ads:adSize="BANNER"
ads:adUnitId="ca-app-pub-5453344383403527/9634376094"
ads:loadAdOnCreate="true" >
</com.google.ads.AdView>
</RelativeLayout>
<RelativeLayout
android:id="@ id/ad_layout"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true" >
<com.google.ads.AdView
android:id="@ id/googleads"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
ads:adSize="BANNER"
ads:adUnitId="ca-app-pub-5453344383403527/2111109291"
ads:loadAdOnCreate="true" >
</com.google.ads.AdView>
</RelativeLayout>
<RelativeLayout
android:id="@ id/functional_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true" >
<ImageButton
android:id="@ id/ButtonTestPlayPause"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:src="@drawable/play_button" />
<SeekBar
android:id="@ id/SeekBarTestPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_toRightOf="@ id/ButtonTestPlayPause" />
</RelativeLayout>
Ответ №4:
Если вы пишете Java-программы для воспроизведения медиафайлов, то первым портом вызова является класс MediaPlayer. Типичный код для воспроизведения файла с использованием механизма потоковой передачи MediaPlayer является
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
Uri uri = Uri.parse("http://192.168.1.9/music/test.ogg");
MediaPlayer player = new MediaPlayer();
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setDataSource(this, uri);
player.prepare();
player.start();
} catch(Exception e) {
System.out.println(e.toString());
}
}
Разрешение на блокировку при пробуждении — если вашему приложению Player необходимо предотвратить затемнение экрана или перевод процессора в спящий режим, или вы используете методы MediaPlayer.setScreenOnWhilePlaying () или MediaPlayer.setWakeMode (), вы должны запросить это разрешение.
<uses-permission android:name="android.permission.WAKE_LOCK" />
Ответ №5:
Я использовал следующее расширение Kotlin для потоковой передачи по URL, используя MediaPlayer
fun ImageButton.playFromUrl(
url: String,
onStart: MediaPlayer.() -> Unit
) {
val audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_MEDIA)
.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
.build()
MediaPlayer().apply {
setAudioAttributes(audioAttributes)
setDataSource(url)
setOnPreparedListener {
isEnabled = false
start()
setImageDrawable(context.getDrawableResource(R.drawable.ic_baseline_stop_24))
}
setOnCompletionListener {
setImageDrawable(context.getDrawableResource(R.drawable.ic_baseline_volume_up_24))
release()
isEnabled = true
}
}.onStart()
}
использование вышеуказанной функции, как показано ниже
btnVoice.setOnSingleClickListener {
if(it.isInternetAvailable()){
(it as ImageButton).playFromUrl(phonetic.audio){
prepareAsync()
}
}
}