java - Exoplayer 音频未在后台服务中播放

标签 java android audio-streaming exoplayer audio-player

所以我开发了一个 Android 应用程序,它使用 exoplayer 库来传输音乐 url。但是,在创建后台服务以在后台启用音乐流后,它不起作用,但当我尝试在前台(MainActivity)时,相同的代码可以工作。

Android list

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.sparrowpaul.musicservice">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name=".BackgroundService"/>

    </application>

</manifest>

MainActivity.Java

    package com.sparrowpaul.musicservice;

    import androidx.appcompat.app.AppCompatActivity;

    import android.content.Intent;
    import android.os.Bundle;

public class MainActivity extends AppCompatActivity {



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent(MainActivity.this, BackgroundService.class);
        startService(intent);



    }


}

BackgroundService.java

public class BackgroundService extends Service implements ExoPlayer.EventListener {

    private Handler mainHandler;
    private RenderersFactory renderersFactory;
    private BandwidthMeter bandwidthMeter;
    private LoadControl loadControl;
    private DataSource.Factory dataSourceFactory;
    private ExtractorsFactory extractorsFactory;
    private MediaSource mediaSource;
    private TrackSelection.Factory trackSelectionFactory;
    private SimpleExoPlayer player;
    private final String streamUrl = "http://bbcwssc.ic.llnwd.net/stream/bbcwssc_mp1_ws-einws";
    private TrackSelector trackSelector;

    @Override
    public void onCreate() {
        super.onCreate();
        startPlayer();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        startPlayer();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    public void startPlayer(){

        renderersFactory = new DefaultRenderersFactory(getApplicationContext());
        bandwidthMeter = new DefaultBandwidthMeter();
        trackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
        trackSelector = new DefaultTrackSelector(trackSelectionFactory);
        loadControl = new DefaultLoadControl();

        player = ExoPlayerFactory.newSimpleInstance(this, renderersFactory, trackSelector, loadControl);

        player.addListener(this);

        dataSourceFactory = new DefaultDataSourceFactory(getApplicationContext(), "ExoplayerDemo");
        extractorsFactory = new DefaultExtractorsFactory();
        mainHandler = new Handler();
        mediaSource = new ExtractorMediaSource(Uri.parse(streamUrl),
                dataSourceFactory,
                extractorsFactory,
                mainHandler,
                null);

        player.prepare(mediaSource);
    }

}

最佳答案

您需要以 foreground service 身份启动您的服务并为此提供通知。 ExoPlayer 的 ui 模块带有 PlayerNotificationManager which helps you with the notification

大概你需要start your service as as a foreground service in your activity 。然后,一旦您的服务创建了通知,您就需要调用 startForeground(notificationId, notification)。如果您不作为前台服务启动,系统将在短时间内停止您的服务。另请参阅此处:https://developer.android.com/guide/components/services#Foreground

下面的示例展示了如何使用 ExoPlayers 通知管理器。

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
  if (player == null) {
    startPlayer();
    playerNotificationManager = new PlayerNotificationManager(
        this, CHANNEL_ID, NOTIFICATION_ID,
        createMediaDescriptionAdapter(),
        new PlayerNotificationManager.NotificationListener() {
          @Override
          public void onNotificationPosted(int notificationId, Notification notification, boolean ongoing) {
            startForeground(notificationId, notification);
          }
          @Override
          public void onNotificationCancelled(int notificationId, boolean dismissedByUser) {
            if (dismissedByUser) {
              // Do what the app wants to do when dismissed by the user,
              // like calling stopForeground(true); or stopSelf();
            }
          }
    });
    playerNotificationManager.setPlayer(player);
  }
  return START_STICKY;
}

关于java - Exoplayer 音频未在后台服务中播放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58657511/

相关文章:

java - ProcessBuilder 中的逃逸空间

java - JAR 文件在 Windows 启动时由 C++ 应用程序启动时不会运行

Android onResume 在 onNewIntent 之后没有被调用

android - 从Android R不推荐使用AsyncTask。是否有其他替代代码?

android - 在 Android 中播放 PCM 流

java - 如何使用java检查24H是否已经过去?

java - 使用 string.split java 将一个字符串分成两个

Chrome 72 更新后 Android Cordova 应用渲染缓慢

python - 使用一个 pyaudio 流进行数据读取和写入

audio - 如何将 24 位音频流传送到图形?