bccm-player icon indicating copy to clipboard operation
bccm-player copied to clipboard

unable to play local videos in my mobile getting error

Open PURUSHOTHAM-REDDY-N opened this issue 8 months ago • 2 comments

  1. i have the permission to read file and media

i'm able to list all the file in a directory but when i tried to play a video , im getting this error

I/flutter (27484): thuis is string im getting at videoplayer screen I/flutter (27484): file:///storage/emulated/0/Movies/WhatsApp//VID-20240406-WA0050.mp4 I/flutter (27484): player replace E/Parcel (27484): Reading a NULL string not supported here. D/bccm (27484): onMediaItemTransitionmedia.bcc.bccm_player.pigeon.PlaybackPlatformApi$PlaybackListenerPigeon@8b9110eevent:media.bcc.bccm_player.pigeon.PlaybackPlatformApi$MediaItemTransitionEvent@1db3c4b7 D/bccm (27484): onMediaItemTransitionmedia.bcc.bccm_player.pigeon.PlaybackPlatformApi$PlaybackListenerPigeon@8b9110eevent:media.bcc.bccm_player.pigeon.PlaybackPlatformApi$MediaItemTransitionEvent@1db3c4b7 D/bccm (27484): playbackState: 2 E/LoadTask(27484): Unexpected exception loading stream E/LoadTask(27484): java.lang.ClassCastException: sun.net.www.protocol.file.FileURLConnection cannot be cast to java.net.HttpURLConnection E/LoadTask(27484): at androidx.media3.datasource.DefaultHttpDataSource.openConnection(DefaultHttpDataSource.java:686) E/LoadTask(27484): at androidx.media3.datasource.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:644) E/LoadTask(27484): at androidx.media3.datasource.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:559) E/LoadTask(27484): at androidx.media3.datasource.DefaultHttpDataSource.open(DefaultHttpDataSource.java:399) E/LoadTask(27484): at androidx.media3.datasource.cache.CacheDataSource.openNextSource(CacheDataSource.java:799) E/LoadTask(27484): at androidx.media3.datasource.cache.CacheDataSource.open(CacheDataSource.java:612) E/LoadTask(27484): at androidx.media3.datasource.StatsDataSource.open(StatsDataSource.java:86) E/LoadTask(27484): at androidx.media3.exoplayer.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1029) E/LoadTask(27484): at androidx.media3.exoplayer.upstream.Loader$LoadTask.run(Loader.java:421) E/LoadTask(27484): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) E/LoadTask(27484): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) E/LoadTask(27484): at java.lang.Thread.run(Thread.java:1012) E/ExoPlayerImplInternal(27484): Playback error E/ExoPlayerImplInternal(27484): androidx.media3.exoplayer.ExoPlaybackException: Source error E/ExoPlayerImplInternal(27484): at androidx.media3.exoplayer.ExoPlayerImplInternal.handleIoException(ExoPlayerImplInternal.java:717) E/ExoPlayerImplInternal(27484): at androidx.media3.exoplayer.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:693) E/ExoPlayerImplInternal(27484): at android.os.Handler.dispatchMessage(Handler.java:102) E/ExoPlayerImplInternal(27484): at android.os.Looper.loopOnce(Looper.java:233) E/ExoPlayerImplInternal(27484): at android.os.Looper.loop(Looper.java:344) E/ExoPlayerImplInternal(27484): at android.os.HandlerThread.run(HandlerThread.java:67) E/ExoPlayerImplInternal(27484): Caused by: androidx.media3.exoplayer.upstream.Loader$UnexpectedLoaderException: Unexpected ClassCastException: sun.net.www.protocol.file.FileURLConnection cannot be cast to java.net.HttpURLConnection E/ExoPlayerImplInternal(27484): at androidx.media3.exoplayer.upstream.Loader$LoadTask.run(Loader.java:442) E/ExoPlayerImplInternal(27484): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) E/ExoPlayerImplInternal(27484): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:644) E/ExoPlayerImplInternal(27484): at java.lang.Thread.run(Thread.java:1012) E/ExoPlayerImplInternal(27484): Caused by: java.lang.ClassCastException: sun.net.www.protocol.file.FileURLConnection cannot be cast to java.net.HttpURLConnection E/ExoPlayerImplInternal(27484): at androidx.media3.datasource.DefaultHttpDataSource.openConnection(DefaultHttpDataSource.java:686) E/ExoPlayerImplInternal(27484): at androidx.media3.datasource.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:644) E/ExoPlayerImplInternal(27484): at androidx.media3.datasource.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:559) E/ExoPlayerImplInternal(27484): at androidx.media3.datasource.DefaultHttpDataSource.open(DefaultHttpDataSource.java:399) E/ExoPlayerImplInternal(27484): at androidx.media3.datasource.cache.CacheDataSource.openNextSource(CacheDataSource.java:799) E/ExoPlayerImplInternal(27484): at androidx.media3.datasource.cache.CacheDataSource.open(CacheDataSource.java:612) E/ExoPlayerImplInternal(27484): at androidx.media3.datasource.StatsDataSource.open(StatsDataSource.java:86) E/ExoPlayerImplInternal(27484): at androidx.media3.exoplayer.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:1029) E/ExoPlayerImplInternal(27484): at androidx.media3.exoplayer.upstream.Loader$LoadTask.run(Loader.java:421) E/ExoPlayerImplInternal(27484): ... 3 more E/IMGSRV (27484): :539: PVRSRVBridgeCall: Bridge call failed. sBridgePackage.ui32BridgeID:0x6, Function ID:0x2a errno 22 (Invalid argument).

this is my main.dart

import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_video_player/src/pages/home_page.dart';
import 'package:bccm_player/bccm_player.dart';
import 'package:flutter_video_player/src/widgets/show_video_files.dart';
import 'package:app_links/app_links.dart';
import 'package:permission_handler/permission_handler.dart';

void main() {
  startPlayer();
  runApp(const MyApp());
}

startPlayer() async {
  WidgetsFlutterBinding.ensureInitialized();
  await BccmPlayerInterface.instance.setup();
  BccmPlayerController.primary.initialize();
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      home: const IntentWidget(title: "hello"),
    );
  }
}

class IntentWidget extends StatefulWidget {
  const IntentWidget({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  State<IntentWidget> createState() => _IntentWidgetState();
}

class _IntentWidgetState extends State<IntentWidget> {
  Uri? _initialURI;
  Uri? _currentURI;
  Object? _err;

  final AppLinks _appLinks = AppLinks();
  StreamSubscription<Uri>? _streamSubscription;

  @override
  void initState() {
    super.initState();
    requestPermissions();
    _handleInitialUri();
    _handleIncomingLinks();
  }

  Future<void> requestPermissions() async {
    // Ask for storage permission (for Android < 11)
    var storageStatus = await Permission.storage.request();

    // Ask for manage external storage (for Android 11+)
    var manageStorageStatus = await Permission.manageExternalStorage.request();

    if (storageStatus.isGranted || manageStorageStatus.isGranted) {
      print("✅ Permissions granted");
    } else {
      print("❌ Permissions denied");
      // You can show a dialog or navigate to app settings
      openAppSettings();
    }
  }

  Future<void> _handleInitialUri() async {
    try {
      final uri = await _appLinks.getInitialLink();
      if (uri != null) {
        debugPrint("Initial URI received: $uri");
        if (!mounted) return;
        setState(() {
          _initialURI = uri;
        });
      } else {
        debugPrint("No initial URI received");
      }
    } on PlatformException {
      debugPrint("Failed to receive initial URI");
    } on FormatException catch (err) {
      if (!mounted) return;
      debugPrint('Malformed initial URI received');
      setState(() => _err = err);
    }
  }

  void _handleIncomingLinks() {
    if (!kIsWeb) {
      _streamSubscription = _appLinks.uriLinkStream.listen((Uri? uri) {
        if (!mounted) return;
        debugPrint('Received URI: $uri');
        setState(() {
          _currentURI = uri;
          _err = null;
        });
      }, onError: (Object err) {
        if (!mounted) return;
        debugPrint('Error occurred: $err');
        setState(() {
          _currentURI = null;
          if (err is FormatException) {
            _err = err;
          } else {
            _err = null;
          }
        });
      });
    }
  }

  @override
  void dispose() {
    _streamSubscription?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (_initialURI == null) {
      return const Scaffold(
        body: HomePage(
          title: "video player",
        ),
      );
    } else {
      return VideoPlayerScreen(path: _initialURI.toString());
    }
  }
}

this is my vide player screen

import 'package:flutter/material.dart';
import 'package:bccm_player/bccm_player.dart';

class VideoPlayerScreen extends StatefulWidget {
  final String path;

  VideoPlayerScreen({required this.path});

  @override
  _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  @override
  void initState() {
    final uri = Uri.file(widget.path);
    print("thuis is string im getting at videoplayer screen");
    print(uri.toString());
    BccmPlayerController.primary.replaceCurrentMediaItem(
        MediaItem(
          url: uri.toString(),
          mimeType: 'video/*',
          metadata: MediaMetadata(title: 'TEST'),
        ),
        autoplay: true);

    super.initState();
  }

  @override
  void dispose() {
    BccmPlayerController.primary.pause();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      body: ListView(
        children: [
          Center(
            child: Column(
              children: [
                VideoPlatformView(
                  playerController: BccmPlayerController.primary,
                  showControls: true,
                  useSurfaceView: true,
                ),
                // ElevatedButton(
                //     onPressed: () =>
                //         BccmPlayerController.primary.enterNativeFullscreen(),
                //     child: Text("enter"))
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Thanks in advance

PURUSHOTHAM-REDDY-N avatar Apr 19 '25 21:04 PURUSHOTHAM-REDDY-N

@KillerX @sifferhans I am able to play local files now changes i made to achieve this :

https://github.com/bcc-code/bccm-player/blob/f215f470e0b01483a01c5cdd56b258f4b062aba6/android/src/main/kotlin/media/bcc/bccm_player/players/exoplayer/ExoPlayerController.kt#L56

i removed above referenced line from the android/src/main/kotlin/media/bcc/bccm_player/players/exoplayer/ExoPlayerController.kt

its working now .

but i want to know will it break anything else , (note : now i am able to play both local and http files )

Thank you in advance

PURUSHOTHAM-REDDY-N avatar Apr 20 '25 05:04 PURUSHOTHAM-REDDY-N

@PURUSHOTHAM-REDDY-N Thanks for reporting! Will take a look when I have time

sifferhans avatar Apr 20 '25 12:04 sifferhans