jhomlala / betterplayer

Better video player for Flutter, with multiple configuration options. Solving typical use cases!
Apache License 2.0
931 stars 1.03k forks source link

[BUG] App Crashing on IOS while playing video #1012

Open juzejunior opened 2 years ago

juzejunior commented 2 years ago

Describe the bug Hello, we´ve been getting some crashes at IOS MediaPlayer via crashlytics, while reproducing some videos with better player. We use HLS video format.

Error at: com.apple.MediaPlayer.MPNowPlayingInfoCenter/accessQueue EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000100000018 ___MPToMRNowPlayingInfoDictionary_block_invoke

Crashed: com.apple.MediaPlayer.MPNowPlayingInfoCenter/accessQueue 0 libobjc.A.dylib 0x1d2c objc_msgSend + 44 1 MediaPlayer 0x23f53c ___MPToMRNowPlayingInfoDictionary_block_invoke + 256 2 CoreFoundation 0x3d378 __NSDICTIONARY_IS_CALLING_OUT_TO_A_BLOCK__ + 16 3 CoreFoundation 0x70bf8 -[__NSFrozenDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 188 4 MediaPlayer 0x23f2fc _MPToMRNowPlayingInfoDictionary + 200 5 MediaPlayer 0x61598 -[MPNowPlayingInfoCenter(NowPlayingInfo) _onQueue_pushNowPlayingInfoAndRetry:] + 268 6 libdispatch.dylib 0x63094 _dispatch_call_block_and_release + 24 7 libdispatch.dylib 0x64094 _dispatch_client_callout + 16 8 libdispatch.dylib 0x3f4a4 _dispatch_lane_serial_drain$VARIANT$armv81 + 600 9 libdispatch.dylib 0x3ff44 _dispatch_lane_invoke$VARIANT$armv81 + 388 10 libdispatch.dylib 0x498e0 _dispatch_workloop_worker_thread + 608 11 libsystem_pthread.dylib 0x1e10 _pthread_wqthread + 284 12 libsystem_pthread.dylib 0x193c start_wqthread + 8

Most of 95% of report came from IOS 15.

Expected behavior Video continues playing without crashing the app.

Screenshots

https://user-images.githubusercontent.com/17789097/170125565-6172a83e-8cd1-4f5c-bfa3-e025aeea3fd0.mp4

Better Player version

Smartphone (please complete the following information):

ptsekov commented 2 years ago

Hello,

It appears the code crashes in the iOS notification handling code. I would guess that the notification is not setup properly. Would you mind posting a minimal example on how you setup the notification?

ptsekov commented 2 years ago

I am attaching a more readable stacktrace:

Crashed: com.apple.MediaPlayer.MPNowPlayingInfoCenter/accessQueue 0 libobjc.A.dylib
0x1d2c objc_msgSend + 44 1 MediaPlayer
0x23f53c ___MPToMRNowPlayingInfoDictionary_block_invoke + 256 2 CoreFoundation
0x3d378 __NSDICTIONARY_IS_CALLING_OUT_TO_A_BLOCK__ + 16 3 CoreFoundation
0x70bf8 -[__NSFrozenDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 188 4 MediaPlayer
0x23f2fc _MPToMRNowPlayingInfoDictionary + 200 5 MediaPlayer
0x61598 -[MPNowPlayingInfoCenter(NowPlayingInfo) _onQueue_pushNowPlayingInfoAndRetry:] + 268 6 libdispatch.dylib
0x63094 _dispatch_call_block_and_release + 24 7 libdispatch.dylib
0x64094 _dispatch_client_callout + 16 8 libdispatch.dylib
0x3f4a4 _dispatch_lane_serial_drain$VARIANT$armv81 + 600 9 libdispatch.dylib
0x3ff44 _dispatch_lane_invoke$VARIANT$armv81 + 388 10 libdispatch.dylib
0x498e0 _dispatch_workloop_worker_thread + 608 11 libsystem_pthread.dylib
0x1e10 _pthread_wqthread + 284 12 libsystem_pthread.dylib
0x193c start_wqthread + 8
juzejunior commented 2 years ago

Hello @ptsekov, sorry for the delay.


  final GPPlayerVideos options;
  DatasourceManager({
    required this.options,
  });
  List<CustomPlayerDataSource> get datasources => this
      .options
      .getPlaylist()
      .map((option) => CustomPlayerDataSource(
            option: option,
            url: option.path,
            type: _convertType(option.type),
            isLive: option.isLive,
            notificationConfiguration: BetterPlayerNotificationConfiguration(
              showNotification: true,
              title: option.title,
              imageUrl: option.thumb,
              author: "Staart",
            ),
            bufferingConfiguration: Configutation.getBufferConfig(),
          ))
      .toList();
  int _currentGettedIndex = -1;
  BetterPlayerDataSourceType _convertType(GPPlayerVideoType type) {
    if (type == GPPlayerVideoType.downloaded) {
      return BetterPlayerDataSourceType.file;
    } else {
      return BetterPlayerDataSourceType.network;
    }
  }
  CustomPlayerDataSource get({String id = ""}) {
    var _datasources = datasources;
    if (id.isEmpty) {
      var dtsc =
          _datasources.firstWhere((e) => e.id == options.statWithOptionId);
      _currentGettedIndex = _datasources.indexWhere((e) => e.id == dtsc.id);
      return dtsc;
    } else {
      var dtsc = _datasources.firstWhere((e) => e.id == id);
      _currentGettedIndex = _datasources.indexWhere((e) => e.id == dtsc.id);
      return dtsc;
    }
  }
  CustomPlayerDataSource getNext() {
    if (_currentGettedIndex >= 0) {
      var newIndex = _currentGettedIndex + 1;
      if (newIndex < datasources.length) {
        _currentGettedIndex = newIndex;
        return datasources[newIndex];
      } else {
        _currentGettedIndex = 0;
        return datasources[0];
      }
    } else {
      return get();
    }
  }
  CustomPlayerDataSource getCurrent() {
    return datasources[_currentGettedIndex];
  }
  bool hasPlaylist() {
    return datasources.length > 1;
  }
}```