2

I'm trying to create an app where I can switch videos with swipes (similar to TikTok). My current implementation looks like this:

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    List<String> urls = [
      "https://movietrailers.apple.com/movies/oscilloscope/relaxer/relaxer-trailer-1_720p.mov",
      "https://movietrailers.apple.com/movies/sony_pictures/the-front-runner/front-runner-trailer-1_720p.mov",
      "https://movietrailers.apple.com/movies/independent/cant-stop-wont-stop-a-bad-boy-story/cant-stop-wont-stop-trailer-1_720p.mov",
      "https://movietrailers.apple.com/movies/independent/at-first-light/at-first-light-trailer-1_720p.mov"
    ];

    return MaterialApp(
      home: PageView.builder(
        itemBuilder: (ctx, index) => VideoScreen(url: urls[index]),
        itemCount: urls.length,
        scrollDirection: Axis.vertical,
      ),
    );
  }
}

class VideoScreen extends StatefulWidget {
  final String url;
  const VideoScreen({Key? key, required this.url}) : super(key: key);

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

class _VideoScreenState extends State<VideoScreen> {
  late VideoPlayerController controller;

  void initController() async {
    controller = VideoPlayerController.network(widget.url);
    await controller.initialize();
    controller.play();
  }

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

  @override
  Widget build(BuildContext context) {
    if (controller.value.isInitialized) {
      return const CircularProgressIndicator();
    }

    return SizedBox(
      height: double.infinity,
      child: AspectRatio(
        aspectRatio: controller.value.aspectRatio,
        child: VideoPlayer(controller),
      ),
    );
  }
}

However, each initialization call o VideoPlayerController entails a complete freeze of the application for the duration of the video download. During this, I am not able to perform any actions in the application.

I'm using the newest version of package in my pubspec.yaml: video_player: ^2.2.16. Here is the output of the flutter doctor command:

% flutter doctor -v
[✓] Flutter (Channel stable, 2.5.1, on macOS 12.1 21C52 darwin-arm, locale ru-RU)
    • Flutter version 2.5.1 at /Users/rkfcccccc/documents/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ffb2ecea52 (5 months ago), 2021-09-17 15:26:33 -0400
    • Engine revision b3af521a05
    • Dart version 2.14.2

[!] Android toolchain - develop for Android devices (Android SDK version 31.0.0)
    • Android SDK at /Users/rkfcccccc/Library/Android/sdk
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.

[✓] Xcode - develop for iOS and macOS
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 13.2.1, Build version 13C100
    • CocoaPods version 1.11.2

[✗] Chrome - develop for the web (Cannot find Chrome executable at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome)
    ! Cannot find Chrome. Try setting CHROME_EXECUTABLE to a Chrome executable.

[!] Android Studio (not installed)
    • Android Studio not found; download from https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).

[✓] VS Code (version 1.63.2)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.32.0

[✓] Connected device (1 available)
    • rkfcccccc (mobile) iOS 15.2.1 19C63
rkfcccccc
  • 21
  • 5

2 Answers2

0

Consider making use of state management such as Provider to handle the logic to initialize incoming indices and play current index. The same will be used to pause/remove the controller once the index is changed to a succeeding or preceding index.

  • I tried several different implementations and unfortunately I couldn't avoid the freeze. Maybe you can update your answer by giving some working example? – rkfcccccc Aug 13 '22 at 18:59
0

just make sure you dispose your controller inside your VideoScreen

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
Mohamed Shawky
  • 159
  • 2
  • 4