unable to play local videos in my mobile getting error
- 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
@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 Thanks for reporting! Will take a look when I have time