Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to play video for local files (under assets) on Android #711

Closed
wuujiann opened this issue Feb 21, 2024 · 4 comments
Closed

Unable to play video for local files (under assets) on Android #711

wuujiann opened this issue Feb 21, 2024 · 4 comments

Comments

@wuujiann
Copy link

First of all, thanks for creating such a fantastic package!

Problem description
I'm unable to play video for local files (under assets) on Android using media_kit package. The window is stuck in the CircularProgressIndicator. No problem if I play a network file (http), or on Windows platform. In addition, if I use video_player & video_player_media_kit package, there is no problem.

The screenshots below compares the output from Windows and Android.

  • top frame - plays a local video file using video_player and video_player_media_kit packages.
  • middle frame - plays a network (http) video file using media_kit package.
  • bottom frame - plays a local video file using media_kit package.

media_kit_comparison

Below is the program for problem reproduction.

import 'package:flutter/material.dart';
import 'package:media_kit/media_kit.dart';
import 'package:media_kit_video/media_kit_video.dart';
import 'package:video_player/video_player.dart';
import 'package:video_player_media_kit/video_player_media_kit.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  MediaKit.ensureInitialized();
  VideoPlayerMediaKit.ensureInitialized(
    android: true,
    iOS: true,
    macOS: true,
    windows: true,
    linux: true,
  );

  runApp(const VideoApp());
}

class VideoApp extends StatefulWidget {
  const VideoApp({super.key});

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

class _VideoAppState extends State<VideoApp> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Video Demo',
      home: Scaffold(
        body: Column(
          children: [
            Expanded(flex: 1, child: VideoPlayerWidget('assets/video1.mkv')),
            Expanded(
              flex: 1,
              child: MediaKitPlayer(
                  'https://user-images.githubusercontent.com/28951144/229373695-22f88f13-d18f-4288-9bf1-c3e078d83722.mp4'),
            ),
            Expanded(
              flex: 1,
              child: MediaKitPlayer('assets/video1.mp4'),
            ),
          ],
        ),
      ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    // _controller.dispose();
  }
}

//----------------------------------------------------------------
class MediaKitPlayer extends StatefulWidget {
  final String videoPath;
  const MediaKitPlayer(this.videoPath, {Key? key}) : super(key: key);

  @override
  State<MediaKitPlayer> createState() => _MediaKitPlayerState(videoPath);
}

class _MediaKitPlayerState extends State<MediaKitPlayer> {
  final String videoPath;
  _MediaKitPlayerState(this.videoPath);

  late final player = Player();
  late final controller = VideoController(player);

  @override
  void initState() {
    super.initState();
    // Play a [Media] or [Playlist].
    player.open(Media(videoPath));
    player.setPlaylistMode(PlaylistMode.loop);
  }

  @override
  void dispose() {
    player.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: SizedBox(
        width: MediaQuery.of(context).size.width,
        height: MediaQuery.of(context).size.width * 9.0 / 16.0,
        // Use [Video] widget to display video output.
        child: Video(controller: controller),
      ),
    );
  }
}

//----------------------------------------------------------------
class VideoPlayerWidget extends StatefulWidget {
  final String videoPath;
  const VideoPlayerWidget(this.videoPath, {super.key});

  @override
  VideoPlayerWidgetState createState() => VideoPlayerWidgetState(videoPath);
}

class VideoPlayerWidgetState extends State<VideoPlayerWidget> {
  final String videoPath;
  VideoPlayerWidgetState(this.videoPath);

  late VideoPlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.asset(videoPath)
      ..initialize().then((_) {
        setState(() {
          _controller.play();
        });
      });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return _controller.value.isInitialized
        ? AspectRatio(
            aspectRatio: _controller.value.aspectRatio,
            child: Stack(
              children: [
                VideoPlayer(_controller),
                playPauseButton(),
              ],
            ),
          )
        : const CircularProgressIndicator();
  }

  Positioned playPauseButton() {
    return Positioned(
      bottom: 10.0,
      left: 0.0,
      right: 0.0,
      child: Center(
        child: IconButton(
          icon: Icon(
            _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
            color: Colors.white,
            size: 30.0,
          ),
          onPressed: () {
            setState(() {
              _controller.value.isPlaying
                  ? _controller.pause()
                  : _controller.play();
            });
          },
        ),
      ),
    );
  }
}
@abdelaziz-mahdy
Copy link
Member

player =
       Player(configuration: PlayerConfiguration(logLevel: MPVLogLevel.debug));
   player.stream.log.listen((event) {
     print("log $event");
   });

check the logs it may show the reason for the failure

@wuujiann
Copy link
Author

wuujiann commented Feb 21, 2024

Thanks for your prompt response! The error is No such file or directory. I tried replacing the filename to /assets/video1.mp4 or media_player/android/app/src/main/assets/video1.mp4, but error remains.

Error Log:

I/flutter ( 3220): <<PLAYER DEBUG>> PlayerLog(prefix: file, level: error, text: Cannot open file 'assets/video1.mp4': No such file or directory)
I/flutter ( 3220): <<PLAYER DEBUG>> PlayerLog(prefix: stream, level: error, text: Failed to open assets/video1.mp4.)

@abdelaziz-mahdy
Copy link
Member

try
'asset:///$asset';

@wuujiann
Copy link
Author

wuujiann commented Feb 21, 2024

It worked!
I changed assets/video1.mp4 to asset:///assets/video1.mp4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants