Anyway to Play MOV video files in Android?

I am trying to play a MOV file in Android app made with flutter. I checked Exoplayer it doesn’t support MOV files. Any idea on how this can be handled? Suppose we are building a gallery app and we want to open MOV files it should be possible.

Sample code

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

void main() => runApp(const VideoApp());

/// Stateful widget to fetch and then display video content.
class VideoApp extends StatefulWidget {
  const VideoApp({super.key});

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

class _VideoAppState extends State<VideoApp> {
  late VideoPlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.networkUrl(Uri.parse(
        'https://filesamples.com/samples/video/mov/sample_1280x720_surfing_with_audio.mov'))
      ..initialize().then((_) {
        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
        setState(() {});
      });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Video Demo',
      home: Scaffold(
        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() {
    _controller.dispose();
    super.dispose();
  }
}

Take a look at media kit: media_kit | Dart package

1 Like

Tried it still not working

import 'package:flutter/material.dart';
// Make sure to add following packages to pubspec.yaml:
// * media_kit
// * media_kit_video
// * media_kit_libs_video
import 'package:media_kit/media_kit.dart'; // Provides [Player], [Media], [Playlist] etc.
import 'package:media_kit_video/media_kit_video.dart'; // Provides [VideoController] & [Video] etc.

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  // Necessary initialization for package:media_kit.
  MediaKit.ensureInitialized();
  runApp(
    const MaterialApp(
      home: MyScreen(),
    ),
  );
}

class MyScreen extends StatefulWidget {
  const MyScreen({Key? key}) : super(key: key);
  @override
  State<MyScreen> createState() => MyScreenState();
}

class MyScreenState extends State<MyScreen> {
  // Create a [Player] to control playback.
  late final player = Player();
  // Create a [VideoController] to handle video output from [Player].
  late final controller = VideoController(player);

  @override
  void initState() {
    super.initState();
    // Play a [Media] or [Playlist].
    player.open(Media(
        'https://filesamples.com/samples/video/mov/sample_1280x720_surfing_with_audio.mov'));
  }

  @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),
      ),
    );
  }
}

Take a look at flutter_vlc_player plugin. VLC has extensive codec support and can handle MOV files effectively.

Tried that also. It just shows a white screen

Logs

Connected to the VM Service.
I/PlatformViewsController(27742): Hosting view in view hierarchy for platform view: 0
I/PlatformViewsController(27742): PlatformView is using SurfaceProducer backend
E/FrameEvents(27742): updateAcquireFence: Did not find frame.
W/Parcel  (27742): Expecting binder but got null!
E/FrameEvents(27742): updateAcquireFence: Did not find frame.
2
W/Parcel  (27742): Expecting binder but got null!
D/nativeloader(27742): Load /data/app/~~hJLU8a2e10BTHJzPO5r1dg==/com.example.video_player_mov-S41yx1OV0jBptPlgLkmuxg==/lib/arm64/libc++_shared.so using ns clns-6 from class loader (caller=/data/app/~~hJLU8a2e10BTHJzPO5r1dg==/com.example.video_player_mov-S41yx1OV0jBptPlgLkmuxg==/base.apk): ok
D/nativeloader(27742): Load /data/app/~~hJLU8a2e10BTHJzPO5r1dg==/com.example.video_player_mov-S41yx1OV0jBptPlgLkmuxg==/lib/arm64/libvlc.so using ns clns-6 from class loader (caller=/data/app/~~hJLU8a2e10BTHJzPO5r1dg==/com.example.video_player_mov-S41yx1OV0jBptPlgLkmuxg==/base.apk): ok
D/nativeloader(27742): Load /data/app/~~hJLU8a2e10BTHJzPO5r1dg==/com.example.video_player_mov-S41yx1OV0jBptPlgLkmuxg==/lib/arm64/libvlcjni.so using ns clns-6 from class loader (caller=/data/app/~~hJLU8a2e10BTHJzPO5r1dg==/com.example.video_player_mov-S41yx1OV0jBptPlgLkmuxg==/base.apk): ok
D/DecorView(27742): isCts, pkg: com.example.video_player_mov
E/FrameEvents(27742): updateAcquireFence: Did not find frame.
D/DecorView(27742): isCts, pkg: com.example.video_player_mov
D/ProfileInstaller(27742): Installing profile for com.example.video_player_mov
Application finished.

Exited.
import 'package:flutter/material.dart';
import 'package:flutter_vlc_player/flutter_vlc_player.dart';

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

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

class _MyHomePageState extends State<MyHomePage> {
  late VlcPlayerController _videoPlayerController;
  
  Future<void> initializePlayer() async {}

  @override
  void initState() {
    super.initState();

    _videoPlayerController = VlcPlayerController.network(
      'https://filesamples.com/samples/video/mov/sample_1280x720_surfing_with_audio.mov',
      hwAcc: HwAcc.full,
      autoPlay: false,
      options: VlcPlayerOptions(),
    );
  }

  @override
  void dispose() async {
    super.dispose();
    await _videoPlayerController.stopRendererScanning();
    await _videoPlayerController.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(),
        body: Center(
          child: VlcPlayer(
            controller: _videoPlayerController,
            aspectRatio: 16 / 9,
            placeholder: const Center(child: CircularProgressIndicator()),
          ),
        ));
  }
}

I got it, this code does work, I already tested it

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

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

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: const VideoPlayerScreen(),
    );
  }
}

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

  @override
  State<VideoPlayerScreen> createState() => _VideoPlayerScreenState();
}

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  late VideoPlayerController _controller;

  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.networkUrl(Uri.parse(
        'https://filesamples.com/samples/video/mov/sample_1280x720_surfing_with_audio.mov'))
      ..initialize().then((_) {
        setState(() {}); // Notifica que el video está inicializado
        _controller.play(); // Comienza a reproducir automáticamente
      }).catchError((error) {
        debugPrint('Error inicializando el video: $error');
      });

    // Opcional: escucha eventos del controlador
    _controller.addListener(() {
      setState(() {});
    });
  }

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

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

If it doesn’t work, check the permissions:

<uses-permission android:name="android.permission.INTERNET"/>

Can you share your device specifications?

Procesador AMD Ryzen 7 5700U with Radeon Graphics 1.80 GHz|
RAM instalada 16,0 GB (15,3 GB usable)|

Edición Windows 11 Home
Versión 24H2
Instalado el ‎02/‎10/‎2024
Versión del sistema operativo 26100.2454
Experiencia Paquete de experiencia de características de Windows 1000.26100.36.0

The Android device which you have tried

Thanks. It was working now. The issue is with tablet and there was a space in URL where the issue originally came.

1 Like