Flutter视频播放插件video_js_player的使用

Flutter视频播放插件video_js_player的使用

一个用于嵌入和控制网络视频播放器(包括Video.js和iframe源)的Flutter包。

特性

  • 支持Video.js和iframe视频源
  • 控制功能包括播放、暂停、拖动进度条、全屏和画中画
  • 可自定义视频播放器设置
  • 集成WebView进行视频播放

安装

在你的pubspec.yaml文件中添加以下依赖:

dependencies:
  video_js_player: x.x.x

示例代码

下面是一个完整的示例代码,展示了如何使用video_js_player插件来播放视频。

import 'package:example/custom_web_player_controller_widget.dart';
import 'package:flutter/material.dart';
import 'package:video_js_player/video_js_player.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.red),
        useMaterial3: true,
      ),
      home: const WelcomePage(),
    );
  }
}

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

  @override
  State<WelcomePage> createState() => _WelcomePageState();
}

class _WelcomePageState extends State<WelcomePage> {
  final TextEditingController _editingController = TextEditingController(
      text:
          "https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8");
  var isIframe = false;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Player"),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          spacing: 8,
          children: [
            TextFormField(
              controller: _editingController,
              decoration: InputDecoration(
                suffixIcon: IconButton(
                  onPressed: () {
                    _editingController.clear();
                  },
                  icon: const Icon(Icons.clear),
                ),
              ),
            ),
            CheckboxListTile(
              value: isIframe,
              contentPadding: const EdgeInsets.symmetric(horizontal: 0),
              onChanged: (v) {
                isIframe = !isIframe;
                setState(() {});
              },
              title: const Text("iFrame"),
            ),
            ElevatedButton(
                onPressed: () {
                  Navigator.push(
                      context,
                      MaterialPageRoute(
                          builder: (_) => HomePage(
                                url: _editingController.text,
                                isIframe: isIframe,
                              )));
                },
                child: const Text("Open Player")),
          ],
        ),
      ),
    );
  }
}

class HomePage extends StatefulWidget {
  final String url;
  final bool isIframe;
  const HomePage({super.key, required this.url, required this.isIframe});

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  var controller = WebVideoPlayerController();

  @override
  void initState() {
    controller.setErrorListener((error) {
      showAdaptiveDialog(
          context: context,
          builder: (c) => AlertDialog(
                title: const Text("Error"),
                content: Text(error),
                actions: [
                  TextButton(
                    onPressed: () => Navigator.pop(context),
                    child: const Text('Ok'),
                  ),
                ],
              ));
    });
    controller.load(widget.isIframe
        ? WebPlayerSource.iframe(widget.url)
        : WebPlayerSource.source(
            WebPlayerVideoSource.source(
              widget.url,
              WebPlayerVideoSourceType.mpegURL,
            ),
            autoPlay: false,
            poster: "https://avatars.githubusercontent.com/u/3287189?s=200&v=4",
            customControlsBuilder: (controller) {
              return CustomWebPlayerController(controller);
            },
          ));

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return WebPlayerBuilder(
        player: WebPlayer(
          controller: controller,
        ),
        builder: (c, player) {
          return Scaffold(
            appBar: AppBar(
              title: const Text("Video JS"),
              actions: [
                IconButton(
                    onPressed: () {
                      controller.toggleFullScreenMode();
                    },
                    icon: const Icon(
                      Icons.fullscreen,
                      color: Colors.red,
                    )),
              ],
            ),
            body: SingleChildScrollView(
              child: Column(
                children: [
                  AspectRatio(aspectRatio: 16 / 9, child: player),
                ],
              ),
            ),
          );
        });
  }
}

说明

  1. 导入必要的库

    import 'package:example/custom_web_player_controller_widget.dart';
    import 'package:flutter/material.dart';
    import 'package:video_js_player/video_js_player.dart';
    
  2. 主应用类 (MyApp):

    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Flutter Demo',
          theme: ThemeData(
            colorScheme: ColorScheme.fromSeed(seedColor: Colors.red),
            useMaterial3: true,
          ),
          home: const WelcomePage(),
        );
      }
    }
    
  3. 欢迎页面 (WelcomePage):

    class WelcomePage extends StatefulWidget {
      const WelcomePage({
        super.key,
      });
    
      @override
      State<WelcomePage> createState() => _WelcomePageState();
    }
    
    class _WelcomePageState extends State<WelcomePage> {
      final TextEditingController _editingController = TextEditingController(
          text: "https://d2zihajmogu5jn.cloudfront.net/bipbop-advanced/bipbop_16x9_variant.m3u8");
      var isIframe = false;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: const Text("Player"),
          ),
          body: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              spacing: 8,
              children: [
                TextFormField(
                  controller: _editingController,
                  decoration: InputDecoration(
                    suffixIcon: IconButton(
                      onPressed: () {
                        _editingController.clear();
                      },
                      icon: const Icon(Icons.clear),
                    ),
                  ),
                ),
                CheckboxListTile(
                  value: isIframe,
                  contentPadding: const EdgeInsets.symmetric(horizontal: 0),
                  onChanged: (v) {
                    isIframe = !isIframe;
                    setState(() {});
                  },
                  title: const Text("iFrame"),
                ),
                ElevatedButton(
                    onPressed: () {
                      Navigator.push(
                          context,
                          MaterialPageRoute(
                              builder: (_) => HomePage(
                                    url: _editingController.text,
                                    isIframe: isIframe,
                                  )));
                    },
                    child: const Text("Open Player")),
              ],
            ),
          ),
        );
      }
    }
    
  4. 视频播放页面 (HomePage):

    class HomePage extends StatefulWidget {
      final String url;
      final bool isIframe;
      const HomePage({super.key, required this.url, required this.isIframe});
    
      @override
      State<HomePage> createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      var controller = WebVideoPlayerController();
    
      @override
      void initState() {
        controller.setErrorListener((error) {
          showAdaptiveDialog(
              context: context,
              builder: (c) => AlertDialog(
                    title: const Text("Error"),
                    content: Text(error),
                    actions: [
                      TextButton(
                        onPressed: () => Navigator.pop(context),
                        child: const Text('Ok'),
                      ),
                    ],
                  ));
        });
        controller.load(widget.isIframe
            ? WebPlayerSource.iframe(widget.url)
            : WebPlayerSource.source(
                WebPlayerVideoSource.source(
                  widget.url,
                  WebPlayerVideoSourceType.mpegURL,
                ),
                autoPlay: false,
                poster: "https://avatars.githubusercontent.com/u/3287189?s=200&v=4",
                customControlsBuilder: (controller) {
                  return CustomWebPlayerController(controller);
                },
              ));
    
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return WebPlayerBuilder(
            player: WebPlayer(
              controller: controller,
            ),
            builder: (c, player) {
              return Scaffold(
                appBar: AppBar(
                  title: const Text("Video JS"),
                  actions: [
                    IconButton(
                        onPressed: () {
                          controller.toggleFullScreenMode();
                        },
                        icon: const Icon(
                          Icons.fullscreen,
                          color: Colors.red,
                        )),
                  ],
                ),
                body: SingleChildScrollView(
                  child: Column(
                    children: [
                      AspectRatio(aspectRatio: 16 / 9, child: player),
                    ],
                  ),
                ),
              );
            });
      }
    }
    

更多关于Flutter视频播放插件video_js_player的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter视频播放插件video_js_player的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


video_js_player 是一个用于在 Flutter 应用中播放视频的插件。它基于 video.js,一个广泛使用的 HTML5 视频播放器。video_js_player 插件允许你在 Flutter 应用中嵌入 video.js 播放器,并支持多种视频格式和流媒体协议。

以下是如何在 Flutter 项目中使用 video_js_player 插件的步骤:

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 video_js_player 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  video_js_player: ^0.0.6  # 请使用最新的版本号

然后运行 flutter pub get 来安装依赖。

2. 导入插件

在你的 Dart 文件中导入 video_js_player 插件:

import 'package:video_js_player/video_js_player.dart';

3. 使用 VideoJsPlayer Widget

VideoJsPlayer 是一个 Widget,你可以像使用其他 Widget 一样使用它。以下是一个简单的例子:

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

class VideoPlayerPage extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Video Player'),
      ),
      body: Center(
        child: VideoJsPlayer(
          src: 'https://www.example.com/video.mp4', // 视频的 URL
          width: 300,
          height: 200,
          autoPlay: true,
          looping: false,
          controls: true,
        ),
      ),
    );
  }
}
回到顶部