flutter_vlc_player icon indicating copy to clipboard operation
flutter_vlc_player copied to clipboard

vlc_flutter_player 7.4.4 throws PlatformException (PlatformException(channel-error, Unable to establish connection on channel., null, null)) on android

Open alohadance98 opened this issue 4 months ago β€’ 22 comments

I have download vlc_flutter_player 7.4.4 and run example app but the vlc throws error PlatformException in example app

D/SurfaceComposerClient(30016): VRR [FRTC] client handle [bufferId:18446744073709551615 framenumber:0] [ffffffff, ffffffff]
E/flutter (30016): [ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null)
E/flutter (30016): #0      VlcPlayerApi.initialize (package:flutter_vlc_player_platform_interface/src/messages/messages.dart:632:7)
messages.dart:632
E/flutter (30016): <asynchronous suspension>
E/flutter (30016): 
I/Choreographer(30016): Skipped 643 frames!  The application may be doing too much work on its main thread.
I/Quality (30016): Skipped: false 643 cost 7149.087 refreshRate 0 processName software.solid.example
D/SurfaceComposerClient(30016): VRR [FRTC] client handle [bufferId:18446744073709551615 framenumber:0] [ffffffff, ffffffff]
I/OpenGLRenderer(30016): Davey! duration=7231ms; Flags=1, FrameTimelineVsyncId=1938030, IntendedVsync=582747303536465, Vsync=582754447980838, InputEventId=0, HandleInputStart=582754453193005, AnimationStart=582754453203370, PerformTraversalsStart=582754453212120, DrawStart=582754481826182, FrameDeadline=582747319758687, FrameInterval=582754452623214, FrameStartTime=11111111, SyncQueued=582754484829516, SyncStart=582754484969099, IssueDrawCommandsStart=582754485829984, SwapBuffers=582754530980557, FrameCompleted=582754535573682, DequeueBufferDuration=725000, QueueBufferDuration=1976875, GpuCompleted=582754535573682, SwapBuffersCompleted=582754534821078, DisplayPresentTime=504607341152, 
I/flutter (30016): [IMPORTANT:flutter/shell/platform/android/platform_view_android.cc(356)] Flutter recommends migrating plugins that create and register surface textures to the new surface producer API. See https://docs.flutter.dev/release/breaking-changes/android-surface-plugins
I/PlatformViewsController(30016): Hosting view in view hierarchy for platform view: 0
I/PlatformViewsController(30016): PlatformView is using SurfaceProducer backend
E/FrameEvents(30016): updateAcquireFence: Did not find frame.
I/Quality (30016): Skipped: false 8 cost 98.39921 refreshRate 0 processName software.solid.example
D/ProfileInstaller(30016): Installing profile for software.solid.example
E/FrameEvents(30016): updateAcquireFence: Did not find frame.

alohadance98 avatar Sep 25 '25 05:09 alohadance98

did you find solution?

FlawLessx avatar Sep 25 '25 08:09 FlawLessx

did you find solution?

I am still waiting for oganize response and hotfix version. I just know after update version of libvlc-all the PlatformException appears

alohadance98 avatar Sep 25 '25 08:09 alohadance98

this issue after the latest library update

Flutter 3.35.3 Platform: Android flutter_vlc_player : 7.4.4

Error message:

P/Quality ( 2103): 07 02 block_gc block_gc otv. player 2103 10510984 1535 I/otv. playe( 2103): WaitForGcToComplete blocked ProfileSaver on HeapTrim for 531.164ms W/Looper ( 2103): Slow delivery took 3386ms main h=android.os.Handler c=io.flutter.embedding.engine.dart.DartMessenger$$ExternalSyntheticLambda0@28db91b m=0 W/Looper ( 2103): Drained E/flutter ( 2103): [ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null) E/flutter ( 2103): #0 VlcPlayerApi.initialize (package:flutter_vlc_player_platform_interface/src/messages/messages.dart:632:7) E/flutter ( 2103): <asynchronous suspension> E/flutter ( 2103): I/PlatformViewsController( 2103): Hosting view in view hierarchy for platform view: 0 I/PlatformViewsController( 2103): PlatformView is using SurfaceProducer backend D/otv. playe( 2103): DDpid=2103 tid=2160 name=com. . player W/Gralloc4( 2103): allocator 3.x is not supported W/Gralloc3( 2103): allocator 3.x is not supported E/FrameEvents( 2103): updateAcquireFence: Did not find frame. D/otv. playe( 2103): DDpid=2103 tid=2160 name=com. . player E/FrameEvents( 2103): updateAcquireFence: Did not find frame. E/flutter ( 2103): [ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null) E/flutter ( 2103): #0 VlcPlayerApi.create (package:flutter_vlc_player_platform_interface/src/messages/messages.dart:658:7) E/flutter ( 2103): <asynchronous suspension> E/flutter ( 2103): #1 VlcPlayerController.initialize (package:flutter_vlc_player/src/vlc_player_controller.dart:191:5) E/flutter ( 2103): <asynchronous suspension> E/flutter ( 2103): #2 VlcPlayerController.onPlatformViewCreated (package:flutter_vlc_player/src/vlc_player_controller.dart:969:7) E/flutter ( 2103): <asynchronous suspension> E/flutter ( 2103): I/otv. playe( 2103): NativeAlloc concurrent copying GC freed 673065(25MB) AllocSpace objects, 0(0B) LOS objects, 49% free, 3076KB/6153KB, paused 134us total 171.812ms

twix44 avatar Sep 25 '25 14:09 twix44

UPDATE: there is a package flutter_vlc_player_16kb on pub.dev which already supports 16kb page size and runs smoothly, you can switch to it @FlawLessx @twix44

alohadance98 avatar Sep 26 '25 03:09 alohadance98

Thanks for the suggestion @alohadance98 , but now im migrating to media_kit since it use libmpv that reduce app size too

FlawLessx avatar Sep 26 '25 06:09 FlawLessx

UPDATE: there is a package flutter_vlc_player_16kb on pub.dev which already supports 16kb page size and runs smoothly, you can switch to it @FlawLessx @twix44

I tried flutter_vlc_player_16Kb but still encountered the same error. Do you have a solution yet?

Zeus178 avatar Sep 29 '25 02:09 Zeus178

Anyone have one solution on this bug ?

rochelryu avatar Sep 29 '25 03:09 rochelryu

this is my error: PlatformException(channel-error, Unable to establish connection on channel., null, null) I/flutter ( 9282): β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ I/flutter ( 9282): β”‚ #0 main. (package:stream_ryu/main.dart:106:12) I/flutter ( 9282): β”‚ #1 _RootZone.runBinary (dart:async/zone.dart:1854:54) I/flutter ( 9282): β”œβ”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„β”„ I/flutter ( 9282): β”‚ β›” Stack trace: #0 VlcPlayerApi.create (package:flutter_vlc_player_platform_interface/src/messages/messages.dart:658:7) I/flutter ( 9282): β”‚ β›” I/flutter ( 9282): β”‚ β›” #1 VlcPlayerController.initialize (package:flutter_vlc_player/src/vlc_player_controller.dart:191:5) I/flutter ( 9282): β”‚ β›” I/flutter ( 9282): β”‚ β›” #2 VlcPlayerController.onPlatformViewCreated (package:flutter_vlc_player/src/vlc_player_controller.dart:969:7) I/flutter ( 9282): β”‚ β›” I/flutter ( 9282): β”‚ β›” I/flutter ( 9282): └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── E/FrameEvents( 9282): updateAcquireFence: Did not find frame. D/EGL_emulation( 9282): app_time_stats: avg=23094.62ms min=23094.62ms max=23094.62ms count=1

this is my code: import 'package:flutter_vlc_player/flutter_vlc_player.dart'; import 'package:stream_ryu/core/utils/logger.dart'; import '../di/service_locator.dart'; import '../storage/secure_storage_local.dart'; import '../utils/channel_helper.dart'; import 'dart:async';

class VlcPlayerService { VlcPlayerController? _controller; bool _isAndroidTV = false; Timer? _healthCheckTimer; Timer? _reconnectTimer; int _bufferHealthChecks = 0; int _reconnectAttempts = 0; static const int _maxReconnectAttempts = 3; String? _lastUrl; String? _lastReferer; String? _lastOrigin; final SecureStorage secureStorage = sl<SecureStorage>(); int? performance;

VlcPlayerController? get controller => _controller;

/// DΓ©tection rapide Android TV void _initializeDeviceInfo(bool isAndroidTV) { _isAndroidTV = isAndroidTV; }

Future loadPerformance() async { performance = await secureStorage.getPerformance(); }

/// PrΓ©pare le player avec stratΓ©gies optimisΓ©es Future<VlcPlayerController> prepare({ required String url, required bool isAndroidTV, String? referer, String? origin, bool autoPlay = true, }) async { _initializeDeviceInfo(isAndroidTV); await loadPerformance();

// Sauvegarde pour reconnexion
_lastUrl = url;
_lastReferer = referer;
_lastOrigin = origin;

// Nettoyage prΓ©ventif
await _cleanupTimers();
_reconnectAttempts = 0;

final strategy = _isAndroidTV
    ? PlayerStrategy.androidTVStable
    : PlayerStrategy.iosBalanced;

return _prepareWithStrategy(url, referer, origin, autoPlay, strategy);

}

Future<VlcPlayerController> _prepareWithStrategy( String url, String? referer, String? origin, bool autoPlay, PlayerStrategy strategy, ) async { if (_controller != null) { await _safeDispose(); }

try {
  final options = _buildOptionsForStrategy(strategy, referer, origin);

  _controller = VlcPlayerController.network(
    url,
    hwAcc: _getHwAccForStrategy(strategy),
    autoPlay: autoPlay,
    options: options,
  );

  // Surveillance pour Android TV
  if (_isAndroidTV) {
    _setupAndroidTVHealthMonitoring();
  }

  return _controller!;
} catch (e) {
  logger.e('Γ‰chec VLC avec stratΓ©gie $strategy: $e');
  rethrow;
}

}

/// Surveillance proactive de la santΓ© du stream void _setupAndroidTVHealthMonitoring() { // Check toutes les 5 secondes (moins agressif) _healthCheckTimer = Timer.periodic(const Duration(seconds: 5), (timer) { _checkStreamHealth(); });

// Surveillance des erreurs
_controller?.addListener(() {
  final state = _controller?.value;
  if (state?.hasError == true) {
    logger.w('Erreur VLC dΓ©tectΓ©e: ${state?.errorDescription}');
    _handleStreamError();
  }
});

}

/// VΓ©rification de la santΓ© du stream void _checkStreamHealth() { final state = _controller?.value; if (state == null || !state.isInitialized) return;

// Si le stream est en buffering trop longtemps
if (state.isBuffering) {
  _bufferHealthChecks++;
  logger.d('Stream en buffering... (${_bufferHealthChecks}/5)');
  
  if (_bufferHealthChecks >= 5) {
    logger.w('Stream bloquΓ© en buffering, tentative de rΓ©cupΓ©ration');
    _handleStreamError();
  }
} else {
  _bufferHealthChecks = 0; // Reset si Γ§a marche
}

// Reset reconnect attempts if playing well
if (state.isPlaying && !state.isBuffering) {
  _reconnectAttempts = 0;
}

}

/// Gestion intelligente des erreurs Future _handleStreamError() async { if (_reconnectAttempts >= _maxReconnectAttempts) { logger.e('Trop de tentatives de reconnexion, abandon'); return; }

_reconnectAttempts++;
_bufferHealthChecks = 0;

logger.i('RΓ©cupΓ©ration automatique $_reconnectAttempts/$_maxReconnectAttempts');

try {
  await _hardRestart();
} catch (e) {
  logger.e('Erreur lors de la rΓ©cupΓ©ration: $e');
}

}

/// RedΓ©marrage complet (plus sΓ»r) Future _hardRestart() async { if (_lastUrl == null) return;

logger.i('Recréation complète du player...');

try {
  await _safeDispose();
  await Future.delayed(const Duration(milliseconds: 1000)); // Plus long pour stabilitΓ©
  
  final options = _buildOptionsForStrategy(
    PlayerStrategy.androidTVStable, 
    _lastReferer, 
    _lastOrigin
  );

  _controller = VlcPlayerController.network(
    _lastUrl!,
    hwAcc: HwAcc.auto,
    autoPlay: true,
    options: options,
  );
  
  if (_isAndroidTV) {
    _setupAndroidTVHealthMonitoring();
  }
} catch (e) {
  logger.e('Hard restart Γ©chouΓ©: $e');
}

}

/// Hardware acceleration conservateur HwAcc _getHwAccForStrategy(PlayerStrategy strategy) { switch (strategy) { case PlayerStrategy.androidTVStable: if(performance == 0) { // Eco logger.d("Eco"); return HwAcc.disabled; } else if (performance == 1) { // Standard logger.d("Standard"); return HwAcc.auto; } else if (performance == 2) { // OptimisΓ© logger.d("OptimisΓ©"); return HwAcc.full; } return HwAcc.disabled; // Auto avec fallback case PlayerStrategy.iosBalanced: return HwAcc.full; } }

/// Options par stratΓ©gie VlcPlayerOptions _buildOptionsForStrategy( PlayerStrategy strategy, String? referer, String? origin, ) { switch (strategy) { case PlayerStrategy.androidTVStable: return _buildAndroidTVStableOptions(referer, origin); case PlayerStrategy.iosBalanced: return _buildIOSFastOptions(referer, origin); } }

/// Configuration Android TV stable (options validΓ©es) VlcPlayerOptions _buildAndroidTVStableOptions(String? referer, String? origin) { final extras = <String>[ '--file-caching=3000', '--network-caching=3000', '--live-caching=3000',

'--no-video-title-show',
'--intf=dummy',

'--http-reconnect',
'--http-user-agent=${getUserAgent()}',

// πŸ”‘ Essentiel : forcer un dΓ©codage plus β€œsouple”
'--avcodec-skiploopfilter=0',
'--avcodec-skip-frame=0',
'--avcodec-hw=any',

// Permet d’éviter le freeze vidΓ©o
'--drop-late-frames',
'--skip-frames',
'--no-sout-video',

'--adaptive-use-access',
'--adaptive-logic=rate',
// '--verbose=2', // temporairement pour debug

];

if (referer != null && referer.isNotEmpty) { extras.add('--http-referrer=$referer'); } if (origin != null && origin.isNotEmpty) { extras.add('--http-origin=$origin'); }

return VlcPlayerOptions( advanced: VlcAdvancedOptions([ VlcAdvancedOptions.networkCaching(3000), ]), video: VlcVideoOptions([ VlcVideoOptions.dropLateFrames(true), VlcVideoOptions.skipFrames(true), ]), audio: VlcAudioOptions([ VlcAudioOptions.audioTimeStretch(true), ]), http: _buildSimpleHttpOptions(referer, origin), extras: extras, ); }

/// iOS options inchangΓ©es VlcPlayerOptions _buildIOSFastOptions(String? referer, String? origin) { final extras = <String>[ '--intf=dummy', '--no-video-title-show',

  '--network-caching=600',
  '--file-caching=300',
  '--live-caching=600',

  '--codec=videotoolbox,avcodec,any',
  '--adaptive-use-access',
  '--adaptive-logic=predictive',
  '--adaptive-maxwidth=1920',
  '--adaptive-maxheight=1080',

  '--http-reconnect',
  '--http-continuous',
  '--http-user-agent=${getUserAgent()}',
  '--no-metadata-network-access',
];

if (referer != null && referer.isNotEmpty) {
  extras.add('--http-referrer=$referer');
}
if (origin != null && origin.isNotEmpty) {
  extras.add('--http-origin=$origin');
}

return VlcPlayerOptions(
  http: _buildSimpleHttpOptions(referer, origin),
  video: VlcVideoOptions([
    VlcVideoOptions.dropLateFrames(true),
  ]),
  extras: extras,
);

}

/// HTTP options simplifiΓ©es VlcHttpOptions _buildSimpleHttpOptions(String? referer, String? origin) { final options = <String>[ VlcHttpOptions.httpReconnect(true), ];

if (referer != null && referer.isNotEmpty) {
  options.add(VlcHttpOptions.httpReferrer(referer));
}

if (origin != null && origin.isNotEmpty) {
  options.add('--http-origin=$origin'); // ajout dans http aussi
}


return VlcHttpOptions(options);

}

/// Nettoyage des timers Future _cleanupTimers() async { _healthCheckTimer?.cancel(); _reconnectTimer?.cancel(); _healthCheckTimer = null; _reconnectTimer = null; }

/// ContrΓ΄les de base Future play() async { try { await _controller?.play(); _reconnectAttempts = 0; logger.d('Lecture dΓ©marrΓ©e'); } catch (e) { logger.e("Erreur play: $e"); if (_isAndroidTV) { await _handleStreamError(); } } }

Future pause() async { try { await _controller?.pause(); logger.d('Lecture mise en pause'); } catch (e) { logger.e("Erreur pause: $e"); } }

Future stop() async { try { await _cleanupTimers(); await _controller?.stop(); logger.d('Lecture arrΓͺtΓ©e'); } catch (e) { logger.e("Erreur stop: $e"); } }

Future dispose() async => _safeDispose();

/// Disposal ultra sΓ©curisΓ© Future _safeDispose() async { await _cleanupTimers();

try {
  await _controller?.stopRendererScanning();
  await _controller?.dispose();
  await Future.delayed(const Duration(milliseconds: 300));
    _controller = null;
    logger.d("VLC disposΓ© proprement");
  } catch (e) {
    logger.e("VLC dispose error: $e");
  }

}

// Getters de base bool get isPlaying => _controller?.value.isPlaying ?? false; bool get isInitialized => _controller?.value.isInitialized ?? false; bool get hasError => _controller?.value.hasError ?? false; bool get isBuffering => _controller?.value.isBuffering ?? false;

// ContrΓ΄les essentiels Future seekTo(Duration position) async { try { await _controller?.seekTo(position); } catch (e) { logger.e("Erreur seek: $e"); } }

Future setVolume(int volume) async { try { await _controller?.setVolume(volume.clamp(0, 100)); } catch (e) { logger.e("Erreur volume: $e"); } }

/// Force une rΓ©cupΓ©ration manuelle Future forceRecover() async { if (_isAndroidTV) { logger.i("RΓ©cupΓ©ration manuelle forcΓ©e"); await _hardRestart(); } }

/// Statistiques de santΓ© Map<String, dynamic> get healthStats => { 'reconnectAttempts': _reconnectAttempts, 'bufferHealthChecks': _bufferHealthChecks, 'isHealthy': _reconnectAttempts == 0 && _bufferHealthChecks < 3, 'hasMonitoring': _healthCheckTimer?.isActive ?? false, }; }

enum PlayerStrategy { androidTVStable, iosBalanced, }

rochelryu avatar Sep 29 '25 03:09 rochelryu

The problem depend of new version flutter stable.

rochelryu avatar Sep 29 '25 04:09 rochelryu

The problem depend of new version flutter stable.

Have you found a solution yet? If so, please share it with me.

Zeus178 avatar Sep 29 '25 04:09 Zeus178

@rochelryu @Zeus178 there is a package fork from vlc_flutter_player which has been fix the error in my comment above

alohadance98 avatar Sep 29 '25 06:09 alohadance98

@rochelryu @Zeus178 there is a package fork from vlc_flutter_player which has been fix the error in my comment above

i tried flutter_vlc_player_16kb: ^7.4.7 but still same err

Zeus178 avatar Sep 29 '25 06:09 Zeus178

Image This modification can solve

hezhipengzipp avatar Sep 29 '25 07:09 hezhipengzipp

Has anyone been able to find a solution to this problem?

CristianCruz-Almanza avatar Sep 29 '25 14:09 CristianCruz-Almanza

@alohadance98 @Zeus178 @CristianCruz-Almanza , flutter_vlc_player_16kb (https://pub.dev/packages/flutter_vlc_player_16kb) solve this problem but, is not stable on live stream.

@hezhipengzipp Which file should we modify on this picture ?

rochelryu avatar Sep 29 '25 19:09 rochelryu

Image After locking the screen and leaving it idle for a while, calling initialize on vlc_player_controller again will result in PlatformException(channel-error, Unable to establish connection on channel: "dev.flutter.pigeon.flutter_vlc_player_platform_interface.VlcPlayerApi.create"., null, null)

hezhipengzipp avatar Sep 30 '25 01:09 hezhipengzipp

Image After locking the screen and leaving it idle for a while, calling initialize on vlc_player_controller again will result in PlatformException(channel-error, Unable to establish connection on channel: "dev.flutter.pigeon.flutter_vlc_player_platform_interface.VlcPlayerApi.create"., null, null)

You can't remove the flutterInjector initialization because FlutterVlcPlayerFactory depends on data provided by that object. specifically injector.flutterLoader()::getLookupKeyForAsset

jorelkimcruz avatar Oct 01 '25 02:10 jorelkimcruz

Has anyone managed to solve this terrible problem?

babayanta1994 avatar Oct 06 '25 10:10 babayanta1994

Hi, running on the same issue as everyone. Playing videos work in a test environment but implementing vlc player in https://github.com/Piwigo/piwigo-flutter-app/pull/228 doesn't.

This result in infinite loading and [ERROR:flutter/runtime/dart_vm_initializer.cc(40)] Unhandled Exception: PlatformException(channel-error, Unable to establish connection on channel., null, null) while trying flutter vlc 16kb will outright crash the app with E/VLC ( 9987): [0000006e60bfb440/27b0] http generic: local stream 1 error: Stream closed (0x5)

Renarde-dev avatar Oct 07 '25 09:10 Renarde-dev

Any updates on this? At the end of this month Play Store force to update all app bundles to 16KB page size but last release is almost not working.

nechtas avatar Oct 21 '25 04:10 nechtas

Hi @nechtas and all. We are busy with other tasks unfortunately, so we can't get on this one right now. But I'm happy to merge any PRs that fix this issue.

illia-romanenko avatar Oct 21 '25 14:10 illia-romanenko

same issue, switching to flutter_vlc_player_16kb fork worked for me, so fixed for now until there's time here to fix it πŸ‘

peter9teufel avatar Oct 25 '25 06:10 peter9teufel