【问题标题】:Flutter audio_service plugin doesn't play audioFlutter audio_service 插件不播放音频
【发布时间】:2021-06-15 17:17:26
【问题描述】:

AudioService.play(); 抛出错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'void io.flutter.plugin.common.MethodChannel.invokeMethod(java.lang.String, java.lang.Object, io.flutter.plugin.common.MethodChannel$Result)' on a null object reference, null, null, null)

调试停止:

 onPressed: () async {
            if (playing) {
              // AudioService.pause();
            } else {
              AudioService.play();
            }
          },

background_audio.dart

import 'package:audio_service/audio_service.dart';
import 'package:just_audio/just_audio.dart';
import 'package:neodiom/api/_queue.dart' as player;
import 'package:neodiom/models/_Track.dart';

// Must be a top-level function
// void _entrypoint() => AudioServiceBackground.run(() => AudioPlayerTask());

class AudioPlayerTask extends BackgroundAudioTask {
  // the Audio player works fine itself and the problem is not related to it
  final _player = player.queue.player; // just_audio player

  // Implement callbacks here. e.g. onStart, onStop, onPlay, onPause
  onPlay() => _player.play();
  onPause() => _player.pause();
  onSeekTo(Duration duration) => _player.seek(duration);
  onSetSpeed(double speed) => _player.setSpeed(speed);

  onStop() async {
    // Stop and dispose of the player.
    await _player.dispose();
    // Shut down the background task.
    await super.onStop();
  }

  onStart(Map<String, dynamic> params) async {
    print(" **** Starting AudioPlayerTask ...");
    // Tell the UI and media notification what we're playing.
    Track t = player.Samples.tracks[0];
    MediaItem m =
        MediaItem(id: t.getTrack, album: t.album['title'], title: t.title);
    AudioServiceBackground.setMediaItem(m);
    _player.currentIndexStream.listen((index) {
      AudioServiceBackground.setMediaItem(player.queue.currentTrackMediaItem);
    });

    // Listen to state changes on the player...
    _player.playerStateStream.listen((playerState) {
      // ... and forward them to all audio_service clients.
      AudioServiceBackground.setState(
        playing: playerState.playing,
        // Every state from the audio player gets mapped onto an audio_service state.
        processingState: {
          ProcessingState.loading: AudioProcessingState.connecting,
          ProcessingState.buffering: AudioProcessingState.buffering,
          ProcessingState.ready: AudioProcessingState.ready,
          ProcessingState.completed: AudioProcessingState.completed,
        }[playerState.processingState],
        // Tell clients what buttons/controls should be enabled in the
        // current state.
        controls: [
          playerState.playing ? MediaControl.pause : MediaControl.play,
          MediaControl.stop,
        ],
      );
    });
  }
}

entrypoint

void _entrypoint() => AudioServiceBackground.run(() => AudioPlayerTask());

main.dart / Service initializer (during App initState)

 void initBackgroundAudioService() async {
    try {
      await AudioService.connect();
      await AudioService.start(
        backgroundTaskEntrypoint: _entrypoint,
        androidNotificationChannelName: 'Audio Service Demo',
        // Enable this if you want the Android service to exit the foreground state on pause.
        //androidStopForegroundOnPause: true,
        androidNotificationColor: 0xFF2196f3,
        androidNotificationIcon: 'mipmap/ic_launcher',
        androidEnableQueue: true,
      );
    } catch (e) {
      print("** Error on start : $e");
    }
  }

【问题讨论】:

  • 您是否完成了audio_service插件pub.dev/packages/audio_service的android设置
  • 您能否澄清您所指的具体“食谱”的问题,以及它是否在 Android 和 iOS 或特定平台上都失败?我相信 ahmetakil 可能指的是 AndroidManifest.xml 文件和 Info.plist(适用于 iOS)。我注意到您在后台任务中也有日志,但在启动和连接时您没有在 UI 中登录,因此我们无法查看事件是否以正确的顺序发生。
  • @RyanHeise Flutter 版本 >=1.12 是否也需要 Android Setup 配置?如果是这样,我还没有实现这些,我必须这样做。 (我的 Flutter 版本是2.0.1)。我在 UI 中也有一个日志,我在 Github 的 latest issue comment 中提到了它,其中 AudioService().start 不会在没有任何错误的情况下触发!
  • 你们说的都对,我忘了添加设置

标签: flutter dart


【解决方案1】:

我只需要按照documentation 中的以下配方遵循操作系统设置(在我的情况下为Android setup instruction

  1. 编辑项目的AndroidManifest.xml 文件以声明创建唤醒锁的权限,并为&lt;service&gt;&lt;receiver&gt; 添加组件条目:
<manifest ...>
  <uses-permission android:name="android.permission.WAKE_LOCK"/>
  <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
  
  <application ...>
    
    ...
    
    <service android:name="com.ryanheise.audioservice.AudioService">
      <intent-filter>
        <action android:name="android.media.browse.MediaBrowserService" />
      </intent-filter>
    </service>

    <receiver android:name="com.ryanheise.audioservice.MediaButtonReceiver" >
      <intent-filter>
        <action android:name="android.intent.action.MEDIA_BUTTON" />
      </intent-filter>
    </receiver> 
  </application>
</manifest>
  1. 从 Flutter 1.12 开始,您需要在 android/app/build.gradle 文件中禁用 shrinkResources 设置,否则在构建过程中将删除 Android 通知中使用的图标资源:
android {
    compileSdkVersion 28

    ...

    buildTypes {
        release {
            signingConfig ...
            shrinkResources false // ADD THIS LINE
        }
    }
}

【讨论】:

    猜你喜欢
    • 2020-12-18
    • 1970-01-01
    • 2023-01-20
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多