Flutter Chewie 视频播放器永远卡在加载中

问题描述 投票:0回答:1

我正在尝试将 Chewie flutter 包实现到我的应用程序中,我把所有内容都记录下来并使其尽可能可定制。它符合要求,但是当我在网络、andriod 或任何可能的设备上运行它时,我得到的只是这个加载屏幕:

这是我的代码:

import '/backend/backend.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/index.dart'; // Imports other custom widgets
import '/custom_code/actions/index.dart'; // Imports custom actions
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom widget code

import 'package:chewie/chewie.dart';
import 'package:video_player/video_player.dart';
import 'dart:io';

class ChewieVideoPlayer extends StatefulWidget {
  ChewieVideoPlayer({
    Key? key,
    this.width,
    this.height,
    this.videoPath,
    this.videosList,
    this.isAutoPlay,
    this.isLooping,
    this.hideControlsAfter,
    this.currentPlayIndex,
    this.startTime,
    this.videoPlatform,
    this.hideControls,
    this.aspectRatio,
    this.disableFullScreen,
    this.isLive,
    this.disableZoomAndPan,
    this.hideOptions,
    this.allowScreenSleep,
    this.disableMuting,
    this.disablePlaybackSpeedChanging,
    this.disableAutoInitialize,
    this.fullScreenByDefault,
    this.playbackSpeedList,
    this.progressIndicatorDelay,
    this.nonDraggableProgressBar,
  }) : super(key: key);

  final double? width;
  final double? height;
  final String? videoPath;
  final List<String>? videosList;
  final bool? isAutoPlay;
  final bool? isLooping;
  final int? hideControlsAfter;
  int? currentPlayIndex;
  final double? startTime;
  final String? videoPlatform;
  final bool? hideControls;
  final double? aspectRatio;
  final bool? disableFullScreen;
  final bool? isLive;
  final bool? disableZoomAndPan;
  final bool? hideOptions;
  final bool? allowScreenSleep;
  final bool? disableMuting;
  final bool? disablePlaybackSpeedChanging;
  final bool? disableAutoInitialize;
  final bool? fullScreenByDefault;
  final List<double>? playbackSpeedList;
  final int? progressIndicatorDelay;
  final bool? nonDraggableProgressBar;
  @override
  State<ChewieVideoPlayer> createState() => _ChewieVideoPlayerState();
}

class _ChewieVideoPlayerState extends State<ChewieVideoPlayer> {
  TargetPlatform? _platform;
  late VideoPlayerController _videoPlayerController1;
  late VideoPlayerController _videoPlayerController2;
  ChewieController? _chewieController;
  late List<String> srcs;

  //Initializing the widget state
  @override
  void initState() {
    super.initState();
    initializePlayer();
    /* srcs = widget.videosList ??
        [
          widget.videoPath ??
          'https://assets.mixkit.co/videos/preview/mixkit-daytime-city-traffic-aerial-view-56-large.mp4']; */
     srcs = [
      'https://assets.mixkit.co/videos/preview/mixkit-daytime-city-traffic-aerial-view-56-large.mp4'
    ];
  }

  //Function to clear the memory to avoid leaks
  @override
  void dispose() {
    _videoPlayerController1.dispose();
    _videoPlayerController2.dispose();
    _chewieController?.dispose();
    super.dispose();
  }

  //Function to initialize the player
  Future<void> initializePlayer() async {
    _videoPlayerController1 = VideoPlayerController.networkUrl(
        Uri.parse(srcs[widget.currentPlayIndex ?? 0]));
    _videoPlayerController2 = VideoPlayerController.networkUrl(
        Uri.parse(srcs[widget.currentPlayIndex ?? 0]));
    await Future.wait([
      _videoPlayerController1.initialize(),
      _videoPlayerController2.initialize()
    ]);

    _createChewieController();
    setState(() {});
  }

//Function that creates ChewieController and custmoize it (e.g. set color, autoplay, looping,etc)
  void _createChewieController() {
    // Check if videoPlatform is provided and set the platform accordingly
    if (widget.videoPlatform != null) {
      switch (widget.videoPlatform) {
        case 'android':
          _platform = TargetPlatform.android;
          break;
        case 'ios':
          _platform = TargetPlatform.iOS;
          break;
        case 'windows':
          _platform = TargetPlatform.windows;
          break;
        default:
          // Handle other cases or leave platform as null
          break;
      }
    }
    final subtitles = [
      Subtitle(
        index: 0,
        start: Duration.zero,
        end: const Duration(seconds: 10),
        text: const TextSpan(
          children: [
            TextSpan(
              text: 'Hello',
              style: TextStyle(color: Colors.red, fontSize: 22),
            ),
            TextSpan(
              text: ' from ',
              style: TextStyle(color: Colors.green, fontSize: 20),
            ),
            TextSpan(
              text: 'subtitles',
              style: TextStyle(color: Colors.blue, fontSize: 18),
            )
          ],
        ),
      ),
      Subtitle(
        index: 0,
        start: const Duration(seconds: 10),
        end: const Duration(seconds: 20),
        text: 'Whats up? :)',
      ),
    ];

    _chewieController = ChewieController(
      videoPlayerController: _videoPlayerController1,
      autoPlay: widget.isAutoPlay ?? false,
      looping: widget.isLooping ?? false,
      hideControlsTimer: Duration(seconds: widget.hideControlsAfter ?? 3),
      showControls: widget.hideControls ?? true,
      startAt: widget.startTime != null
          ? Duration(milliseconds: (widget.startTime! * 1000).toInt())
          : null,
      aspectRatio: widget.aspectRatio ?? 1.7,
      allowFullScreen: !(widget.disableFullScreen ?? false),
      isLive: widget.isLive ?? false,
      zoomAndPan: !(widget.disableZoomAndPan ?? false),
      showOptions: !(widget.hideOptions ?? false),
      allowedScreenSleep: widget.allowScreenSleep ?? false,
      allowMuting: !(widget.disableMuting ?? false),
      allowPlaybackSpeedChanging:
          !(widget.disablePlaybackSpeedChanging ?? false),
      autoInitialize: !(widget.disableAutoInitialize ?? false),
      fullScreenByDefault: widget.fullScreenByDefault ?? false,
      draggableProgressBar: !(widget.nonDraggableProgressBar ?? false),
      playbackSpeeds:
          widget.playbackSpeedList ?? [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2],
      progressIndicatorDelay: widget.progressIndicatorDelay != null
          ? Duration(milliseconds: (widget.progressIndicatorDelay!))
          : null,
      additionalOptions: (context) {
        return <OptionItem>[
          OptionItem(
            onTap: toggleVideo,
            iconData: Icons.live_tv_sharp,
            title: 'Next Video',
          ),
        ];
      },
      subtitle: Subtitles(subtitles),
      subtitleBuilder: (context, dynamic subtitle) => Container(
        padding: const EdgeInsets.all(10.0),
        child: subtitle is InlineSpan
            ? RichText(
                text: subtitle,
              )
            : Text(
                subtitle.toString(),
                style: const TextStyle(color: Colors.black),
              ),
      ),
    );
  }

  //Function to switch to the next video in list
  Future<void> toggleVideo() async {
    await _videoPlayerController1.pause();
    widget.currentPlayIndex = (widget.currentPlayIndex ?? 0) + 1;
    if (widget.currentPlayIndex! >= srcs.length) {
      widget.currentPlayIndex = 0;
    }
    await initializePlayer();
  }

  //Building the widget
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: AppTheme.light.copyWith(
        platform: _platform ?? Theme.of(context).platform,
      ),
      home: Scaffold(
        body: Column(
          children: <Widget>[
            Expanded(
              child: Center(
                child: _chewieController != null && _chewieController!
                  .videoPlayerController.value.isInitialized
                  ? Chewie(controller: _chewieController!,)
                const Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    CircularProgressIndicator(),
                    SizedBox(height: 20),
                    Text('Loading'),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      );
    }
  }

// Theme
class AppTheme {
  static final light = ThemeData(
    brightness: Brightness.light,
    useMaterial3: true,
    colorScheme: const ColorScheme.light(secondary: Colors.red),
    disabledColor: Colors.grey.shade400,
    visualDensity: VisualDensity.adaptivePlatformDensity,
  );

  static final dark = ThemeData(
    brightness: Brightness.dark,
    colorScheme: const ColorScheme.dark(secondary: Colors.red),
    disabledColor: Colors.grey.shade400,
    useMaterial3: true,
    visualDensity: VisualDensity.adaptivePlatformDensity,
  );
}

所以我尝试下载该应用程序,在网络上运行它,在andriod studio上运行它,等等,但没有希望。 我期望简单地让视频播放器播放 videoList(如果它不为空),如果它为空,那么它将使用 videoPath 作为其第一个条目并播放该视频。 我试图删除所有这些逻辑,而是对视频进行硬编码,并尝试了 Chewie 官方文档中使用的几种不同的逻辑,但没有希望。

如果有人能找出可能导致此问题的原因,我将非常感谢您。如果我没记错的话,这可能是我在 ChatGPT 上花了 8 个小时尝试调试它之后遇到的第一个 StackOverFlow 问题,哈哈。

flutter debugging video flutter-dependencies flutter-video-player
1个回答
0
投票

第1步: 在 android>app>build.gradle 中更改compileSdkVersion

来自

compileSdkVersion flutter.compileSdkVersion

compileSdkVersion 34

compileSdkVersion 是在构建过程中编译您的应用程序的 Android SDK 版本。它决定了您可以在代码中使用的 API 和功能集。

所以根据最新版本的chewie包你至少需要compileSdkVersion 24

第2步:添加互联网权限(在debug模式下无需权限即可工作,但在release或debug apk中,如果Android Manifest文件中未添加权限,则不会进行网络调用)

转到 android>app>main>AndroidManifest.xml

<manifest xlmns:android...>
 ...
 <uses-permission android:name="android.permission.INTERNET" /> //TODO: Add this line
 <application ...
</manifest>

第3步:在调用initializePlayer之前初始化您的源(srcs)

void initState() {
    super.initState();
    //TODO: Initialize srcs before initializePlayer()
    srcs = [
      'https://assets.mixkit.co/videos/preview/mixkit-daytime-city-traffic-aerial-view-56-large.mp4'
    ];
    initializePlayer();
    // /* srcs = widget.videosList ??
    //     [
    //       widget.videoPath ??
    //       'https://assets.mixkit.co/videos/preview/mixkit-daytime-city-traffic-aerial-view-56-large.mp4']; */
    // srcs = [
    //   'https://assets.mixkit.co/videos/preview/mixkit-daytime-city-traffic-aerial-view-56-large.mp4'
    // ];
  }
© www.soinside.com 2019 - 2024. All rights reserved.