Search code examples
flutterdartflutter-dependenciesflutter-video-player

How to play mkv file using flutter video_player?


I am trying to play an .mkv file using. flutters video_player and a api link. When i try to play a mp4 video it works, but when i play a mkv video it gives me the error:

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(VideoError, Failed to load video: Cannot Open, null, null)

This is my current code:

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

class VideoPlayerTestScreen extends StatefulWidget {
  final String videoUrl;
  final String username;
  final String password;
  final String streamId;
  final String containerExtension;

  const VideoPlayerTestScreen({
    required this.videoUrl,
    required this.username,
    required this.password,
    required this.streamId,
    required this.containerExtension,
    Key? key,
  }) : super(key: key);

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

class _VideoPlayerTestScreenState extends State<VideoPlayerTestScreen> {
  late VideoPlayerController _controller;

  @override
  void initState() {
    super.initState();
    print('Final Video URL: ${widget.videoUrl}'); // Print the final URL
    _controller = VideoPlayerController.networkUrl(
      Uri.parse(widget.videoUrl),
      httpHeaders: {}, 
    )..initialize().then((_) {
      setState(() {});
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Video Demo'),
      ),
      body: Center(
        child: _controller.value.isInitialized
            ? AspectRatio(
                aspectRatio: _controller.value.aspectRatio,
                child: VideoPlayer(_controller),
              )
            : Container(),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _controller.value.isPlaying
                ? _controller.pause()
                : _controller.play();
          });
        },
        child: Icon(
          _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ),
    );
  }

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

When i enter the api url of the mp4 file in my browser, it shows the video directly on a page. But with the .mkv file it downloads the file to my pc instead of showing it on the page.

I tried searching on stackoverflow, google search and github. Could not find any helping solutions yet.


Solution

  • .mkv is just a container format, support is going to also depend on the codecs used inside it - the file is .mkv but the video could be encoded as H.264, H.265, VP9, etc

    The video_player package has links to the supported formats.

    Supported Formats

    On iOS and macOS, the backing player is AVPlayer. The supported formats vary depending on the version of iOS, AVURLAsset class has audiovisualTypes that you can query for supported av formats.

    On Android, the backing player is ExoPlayer, please refer here for list of supported formats.

    On Web, available formats depend on your users' browsers (vendor and version). Check package:video_player_web for more specific information.

    There is another answer specifically with the supported iOS formats.

    The supported formats for ExoPlayer do include Matroska (mkv) so it should work on Android.

    Supported formats for the web is going to depend on what browser you are using.

    If the video is not already encoded as H.264 I would re-encode as that so it has the most compatibility across browsers.