dart Flutter video_player在传入文件时显示空白视频

vd2z7a6w  于 11个月前  发布在  Flutter
关注(0)|答案(2)|浏览(153)

我从Flutter的摄像机库中获取了一个文件对象,然后将该文件传递到Flutter的video_player控制器中。
第一个月
当我这样做的时候,视频显示完全空白。如果我加入了时间戳,它似乎知道视频的大致长度,但是什么都不播放--没有音频什么都没有。如果我用调用.networkUrl替换调用.file,并传入一个已知的工作视频,我已经能够让它在完全相同的文件中正常工作了。我认为它应该接受一个file对象,而不会有太多问题。
我也试过使用不同的库,朱伊。虽然我并没有期望太多,因为它使用的是视频播放器。它也没有像我预期的那样工作,但我不知道还能尝试什么。
没有错误记录到终端。
编辑以添加更多代码上下文:

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:loading_animation_widget/loading_animation_widget.dart';
import 'package:revvy/utils/getEnv.dart';
import 'package:revvy/utils/styles.dart';
import 'package:revvy/utils/svgs.dart';
import 'package:revvy/widgets/BouncingButton.dart';
import 'package:video_player/video_player.dart';
import 'package:visibility_detector/visibility_detector.dart';

final String S3_BASE_URL = getEnv('S3_BASE_URL');

class VideoPlayerWidget extends StatefulWidget {
  final File? video;
  final String videoKey;
  final bool displayProgress;
  final bool tapToPlay;
  const VideoPlayerWidget({Key? key, this.video, this.videoKey = '', this.displayProgress = false, this.tapToPlay = false}) : super(key: key);

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

class VideoPlayerWidgetState extends State<VideoPlayerWidget> {
  late VideoPlayerController _controller;
  late Future<void> _initializeVideoPlayerFuture;
  double volume = 0;
  double prevVisibleFraction = 0.0;

  @override
  void initState() {
    if (widget.video == null) {
      String url = '$S3_BASE_URL/${widget.videoKey}';
      Uri uri = Uri.parse(url);
      _controller = VideoPlayerController.networkUrl(uri);
    } else {
      _controller = VideoPlayerController.file(widget.video!);
    }

    _initializeVideoPlayerFuture = _controller.initialize();

    _controller.setVolume(1);
    _controller.setLooping(true);

    super.initState();
  }

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

  @override
  void setState(VoidCallback fn) {
    if (mounted) {
      super.setState(fn);
    }
  }

  @override
  Widget build(BuildContext context) {
    final query = MediaQuery.of(context);
    final double width = query.size.width;
    final double height = query.size.height;

    return Container(
      color: Colors.black,
      width: width,
      height: height,
      child: FutureBuilder(
        future: _initializeVideoPlayerFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            return Stack(
              children: [
                ClipRect(
                  clipBehavior: Clip.hardEdge,
                  child: SizedBox.expand(
                    child: FittedBox(
                      fit: BoxFit.cover,
                      child: SizedBox(
                        width: _controller.value.size.width,
                        height: _controller.value.size.height,
                        child: GestureDetector(
                          onTap: () {
                            if (widget.tapToPlay) {
                              if (_controller.value.isPlaying) {
                                _controller.pause();
                              } else {
                                _controller.play();
                              }
                            }
                          },
                          child: VideoPlayer(_controller),
                        ),
                      )
                    )
                  ),
                ),
                Positioned(
                  bottom: 132,
                  left: CONTENT_SPACING_3,
                  right: CONTENT_SPACING_3,
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      if (!widget.tapToPlay) (
                        BouncingButton(
                          onPress: () {
                            setState(() {
                              if (_controller.value.isPlaying) {
                                _controller.pause();
                              } else {
                                _controller.play();
                              }
                            });
                          },
                          child: SizedBox(
                            width: ICON_SIZE_LG,
                            height: ICON_SIZE_LG,
                            child: SvgPicture.string(_controller.value.isPlaying ? faPauseSolid : faPlaySolid, color: Colors.white)
                          ),
                        )
                      ) else (
                          const SizedBox()
                      ),
                      if (widget.displayProgress) (
                        SizedBox(
                          width: width - 200,
                          child: VideoProgressIndicator(
                            _controller,
                            allowScrubbing: true,
                          ),
                        )
                      ),
                      if (widget.displayProgress) (
                        ValueListenableBuilder(
                          valueListenable: _controller,
                          builder: (context, VideoPlayerValue value, child) {
                            final currentTime = value.position.toString();
                            final duration = _controller.value.duration.toString();

                            String formatVideoTime(time) {
                              final values = time.split(':');
                              return '0:' + values[2].split('.')[0];
                            }

                            return Text('${formatVideoTime(currentTime)}/${formatVideoTime(duration)}', style: const TextStyle(fontSize: FONT_SIZE_MD, color: Colors.white));
                          },
                        )
                      ),
                    ]
                  )
                ),
              ]
            );
          } else {
            // If the VideoPlayerController is still initializing, show a
            // loading spinner.
            return Center(
              child: LoadingAnimationWidget.prograssiveDots(
                color: COLOR_PRIMARY,
                size: 64,
              ),
            );
          }
        },
      )
    );
  }
}

字符串

mspsb9vt

mspsb9vt1#

您需要初始化视频播放器。
第一个月
请查看文档中的示例代码。

b4lqfgs4

b4lqfgs42#

class MediaPlayer extends StatefulWidget {
  final MediaModel? mediaModelLocal;

  const MediaPlayer({Key? key, this.mediaModelLocal}) : super(key: key);

  @override
  State<MediaPlayer> createState() => _MediaPlayerState();
}

class _MediaPlayerState extends State<MediaPlayer> {
  ChewieController? chewieController;
  late VideoPlayerController videoPlayerController;
  bool anErrorOccured = false;

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

  Future<void> initializeVideoPlayer() async {
    try {
      late ImageProvider coverImage;
      if (widget.mediaModelLocal?.file is File) {
        videoPlayerController =
            VideoPlayerController.file(widget.mediaModelLocal!.file!);
        coverImage = FileImage(widget.mediaModelLocal!.thumbnailImage!);
      }

      if (widget.mediaModelLocal?.file is String) {
        videoPlayerController = VideoPlayerController.networkUrl(
            Uri.parse(widget.mediaModelLocal!.file!));

        String thumbnailImage;
        if (widget.mediaModelLocal?.thumbnailImage != null &&
            widget.mediaModelLocal?.thumbnailImage is String) {
          thumbnailImage = widget.mediaModelLocal!.thumbnailImage!;
          thumbnailImage = thumbnailImage.getFullImagePath();
          coverImage = NetworkImage(thumbnailImage);
        }
      }

      await videoPlayerController.initialize();
      chewieController = ChewieController(
        showControls: true,
        deviceOrientationsOnEnterFullScreen: [
          DeviceOrientation.portraitUp,
          DeviceOrientation.landscapeLeft,
          DeviceOrientation.landscapeRight
        ],
        allowFullScreen: true,
        videoPlayerController: videoPlayerController,
        autoPlay: false,
        looping: false,
        placeholder: Container(
          decoration: BoxDecoration(
            color: const Color(0XFF281E4F),
            image: DecorationImage(
              fit: BoxFit.cover,
              image: coverImage,
            ),
          ),
          child: BackdropFilter(
            filter: ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
            child: Container(
              decoration: BoxDecoration(color: Colors.black.withOpacity(0.7)),
            ),
          ),
        ),
      );
      setState(() {});
    } catch (e) {
      setState(() {
        anErrorOccured = true;
      });
    }
  }

  @override
  void dispose() {
    videoPlayerController.dispose();
    chewieController?.dispose();
    super.dispose();
  }

  double radius = 8;
  Widget backgroundLayout({required Widget child}) {
    return Container(
        decoration: BoxDecoration(
            color: const Color(0XFF281E4F),
            borderRadius: BorderRadius.all(Radius.circular(radius))),
        child: Center(child: child));
  }

  @override
  Widget build(BuildContext context) {
    var theme = Theme.of(context);
    TextStyle? textStyle =
        theme.textTheme.bodyLarge?.copyWith(color: Colors.white, fontSize: 13);
    if (anErrorOccured == true ||
        chewieController != null &&
            chewieController!.videoPlayerController.value.hasError) {
      return backgroundLayout(
          child: Row(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          const Padding(
            padding: EdgeInsets.only(right: 5.0),
            child: Icon(
              Icons.error_outline_outlined,
              color: Colors.white,
            ),
          ),
          Text(
            'Failed to play video',
            style: textStyle,
          )
        ],
      ));
    }
    if (chewieController != null &&
        chewieController!.videoPlayerController.value.isInitialized) {
      return ClipRRect(
        borderRadius: BorderRadius.circular(radius),
        child: Chewie(
          controller: chewieController!,
        ),
      );
    }

    return backgroundLayout(
        child: const SystemCircularProgressIndicator(
      color: Colors.white,
    ));
  }
}

字符串

相关问题