video_player_rtmp_ext 0.3.1 copy "video_player_rtmp_ext: ^0.3.1" to clipboard
video_player_rtmp_ext: ^0.3.1 copied to clipboard

A player supporting rtmp&rtmps live video

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:video_player_rtmp_ext/models/android_play_manager.dart';
import 'package:video_player_rtmp_ext/models/play_source.dart';
import 'package:video_player_rtmp_ext/models/video_listener_model.dart';
import 'package:video_player_rtmp_ext/widget/video_player_rtmp_ext.dart';

const line1 = 'http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear2/prog_index.m3u8';
const line2 = 'rtmp://ns8.indexforce.com/home/mystream';
const line3 = 'rtmp://mobliestream.c3tv.com:554/live/goodtv.sdp';

void main() {
  runApp( MaterialApp(
    home: _DemoHome(),
  ));
}
class _DemoHome extends StatelessWidget {
  const _DemoHome({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("demo"),),
      body: SingleChildScrollView(
        child: Column(
          children: [
            TextButton(onPressed: (){
              Navigator.of(context).push(MaterialPageRoute(builder: (_)=>LiveBroascasePage()));
            }, child: Text("line 1"))
          ],
        ),
      ),
    );
  }
}


///直播测试页面
class LiveBroascasePage extends StatefulWidget {
  const LiveBroascasePage({super.key});

  @override
  State<LiveBroascasePage> createState() => _LiveBroascasePageState();
}

class _LiveBroascasePageState extends State<LiveBroascasePage> {
  final IJKPlayerController controller = IJKPlayerController(source: PlaySource.network(uri: Uri.parse(line1)));

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final padding = MediaQuery.of(context).padding;
    return Scaffold(
      body: Stack(
        children: [
          AspectRatio(
            aspectRatio: size.width / (size.height - padding.top),
            child: VideoPlayerRtmpExtWidget(
              controller: controller,
              viewCreated: (IJKPlayerController _) async {
                controller.addListener(onStateChange);
                if (controller.isAndroid) {
                  await controller.setPlayManager(PlayerFactory.exo2PlayerManager);
                }
                await controller.play();
              },
            ),
          ),
          Positioned(top: padding.top,left: 0,right: 0,child: Row(
            children: [
              IconButton(onPressed: (){
              }, icon: const Icon(Icons.file_copy)),
              IconButton(onPressed: () async {
                final status = await controller.isPlaying;
                print(status);
              }, icon: const Icon(Icons.safety_check))
            ],
          ),),
          Positioned(
              bottom: padding.bottom,
              left: 0,
              right: 0,
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  IconButton(onPressed: () {
                    controller.resume();
                  }, icon: const Icon(Icons.play_arrow, color: Colors.white)),
                  IconButton(
                      onPressed: () {
                        controller.pause();
                      },
                      icon: const Icon(
                        Icons.pause,
                        color: Colors.white,
                      ))
                ],
              ))
        ],
      ),
    );
  }

  Future<void> pause() async {
    await controller.pause();
  }

  Future<void> stop() async {
    await controller.stop();
  }

  Future<void> isPlaying() async {
    final isPlaying = await controller.isPlaying;
  }

  ///player state change callback
  void onStateChange(VideoListenerModel model){
    debugPrint("状态变化 changed: $model");
    switch(model){
      case ProgressListenerModel():
      case StateListenerModel():
      case OnPlayErrorListenerModel():
    }

  }

  @override
  void dispose() {
    controller.removeListener(onStateChange);
    controller.dispose();
    super.dispose();
  }
}