如何使Flutter视频播放器只在用户点击播放后开始流式传输?

huangapple go评论84阅读模式
英文:

How to make Flutter video player only start streaming after user tap play?

问题

我正在尝试使用Flutter的video_playerchewie。我尝试了以下两个链接中提供的示例:

两者都运行良好。然而,即使用户没有点击屏幕,视频URL也会立即被获取和下载。

我怎样才能推迟视频下载直到用户的操作?

英文:

I am trying Flutter video_player with chewie. I have tried both examples provided in:

Both work fine. Yet, even when the user does not tap on the screen, the video URL is immediately fetched and downloaded.

How can I postpone the video download until the user’s action?

答案1

得分: 1

通过将示例从chewie包中修改并放入StatefulWidget中,我们得到:

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

class ExampleWidget extends StatefulWidget {
  const ExampleWidget({Key? key});

  @override
  State<ExampleWidget> createState() => _ExampleWidgetState();
}

final VideoPlayerController videoPlayerController = VideoPlayerController.network(
    'https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4');

class _ExampleWidgetState extends State<ExampleWidget> {
  late final ChewieController chewieController;
  bool _initialized = false;

  @override
  void initState() {
    chewieController = ChewieController(
        videoPlayerController: videoPlayerController, autoPlay: false, looping: true, autoInitialize: false);
  }

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

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Expanded(
          child: Chewie(controller: chewieController),
        ),
        ElevatedButton(
          onPressed: () async {
            if (!_initialized) {
              await videoPlayerController.initialize();
            }
            _initialized = true;
            await chewieController.play();
          },
          child: const Text("播放"),
        ),
      ],
    );
  }
}

void main() => runApp(MaterialApp(
    home: Scaffold(
        backgroundColor: Colors.green,
        appBar: AppBar(),
        body: Builder(builder: (BuildContext context) => _build(context)))));

Widget _build(BuildContext context) {
  return const ExampleWidget();
}

通过将ChewieController中的autoPlay设置为false,视频将不会自动播放,通过使用chewieController.play(),您可以在按下按钮时启动视频。

为了防止控制器预加载视频,只需在回调方法中初始化videoPlayerController一次,而不是在initState方法中。这将在第一次按下“播放”按钮时加载视频(但请记住,在此示例中,单击视频本身将显示错误符号)。

相反,您还可以在initialized bool为false时显示某种加载小部件,并且只在Video Player可见时显示它,或者在ChewieController中将参数showControls设置为false。

英文:

Modifiying the example from the chewie package and putting it inside of a StatefulWidget, we get:

import &#39;package:flutter/material.dart&#39;;
import &#39;package:video_player/video_player.dart&#39;;
import &#39;package:chewie/chewie.dart&#39;;

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

  @override
  State&lt;ExampleWidget&gt; createState() =&gt; _ExampleWidgetState();
}

final VideoPlayerController videoPlayerController = VideoPlayerController.networkUrl(
    Uri.parse(&#39;https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4&#39;));

class _ExampleWidgetState extends State&lt;ExampleWidget&gt; {
  late final ChewieController chewieController;
  bool _initialized = false;

  @override
  void initState() {
    chewieController = ChewieController(
        videoPlayerController: videoPlayerController, autoPlay: false, looping: true, autoInitialize: false);
  }

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

  @override
  Widget build(BuildContext context) {
    return Column(
      children: &lt;Widget&gt;[
        Expanded(
          child: Chewie(controller: chewieController),
        ),
        ElevatedButton(
          onPressed: () async {
            if (!_initialized) {
              await videoPlayerController.initialize();
            }
            _initialized = true;
            await chewieController.play();
          },
          child: const Text(&quot;Play&quot;),
        ),
      ],
    );
  }
}

void main() =&gt; runApp(MaterialApp(
    home: Scaffold(
        backgroundColor: Colors.green,
        appBar: AppBar(),
        body: Builder(builder: (BuildContext context) =&gt; _build(context)))));

Widget _build(BuildContext context) {
  return const ExampleWidget();
}

By setting the autoPlay from the ChewieController to false, the video will not automatically play and by using the chewieController.play(), you can then start the video on pressing a button.

To also prevent the controller from preloading the video, only initialize the videoPlayerController in the callback method once instead of inside of the initState method.

This will load the video the first time the Play button is pressed (But remember that in this example clicking inside of the video itself would show the error symbol).
Instead you could also display some kind of loading Widget instead while the initialized bool is false and only show the Video Player otherwise. Or set the param showControlsto false inside of the ChewieController.

huangapple
  • 本文由 发表于 2023年7月10日 22:08:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76654576.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定