feat: 直播间播放

This commit is contained in:
guozhigq
2023-07-11 21:32:31 +08:00
parent 75d4e20d99
commit 828b5c39aa
9 changed files with 374 additions and 7 deletions

View File

@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import 'package:flutter_meedu_media_kit/meedu_player.dart';
import 'package:get/get.dart';
import 'package:pilipala/http/constants.dart';
import 'package:pilipala/http/live.dart';
import 'package:pilipala/models/live/room_info.dart';
class LiveRoomController extends GetxController {
String cover = '';
late int roomId;
var liveItem;
MeeduPlayerController meeduPlayerController = MeeduPlayerController(
colorTheme: Theme.of(Get.context!).colorScheme.primary,
pipEnabled: true,
controlsStyle: ControlsStyle.youtube,
enabledButtons: const EnabledButtons(pip: true),
);
@override
void onInit() {
super.onInit();
var args = Get.arguments['liveItem'];
liveItem = args;
print(liveItem.roomId);
roomId = liveItem.roomId!;
if (args.pic != null && args.pic != '') {
cover = args.cover;
}
queryLiveInfo();
}
playerInit(source) {
meeduPlayerController.setDataSource(
DataSource(
type: DataSourceType.network,
source: source,
httpHeaders: {
'user-agent':
'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_3_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15',
'referer': HttpString.baseUrl
},
),
autoplay: true,
);
}
Future queryLiveInfo() async {
var res = await LiveHttp.liveRoomInfo(roomId: roomId, qn: 10000);
if (res['status']) {
List<CodecItem> codec =
res['data'].playurlInfo.playurl.stream.first.format.first.codec;
CodecItem item = codec.first;
String videoUrl = (item.urlInfo?.first.host)! +
item.baseUrl! +
item.urlInfo!.first.extra!;
playerInit(videoUrl);
}
}
}

View File

@ -0,0 +1,4 @@
library liveroom;
export './controller.dart';
export './view.dart';

View File

@ -0,0 +1,110 @@
import 'package:flutter/material.dart';
import 'package:flutter_meedu_media_kit/meedu_player.dart';
import 'package:get/get.dart';
import 'dart:ui';
import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'controller.dart';
class LiveRoomPage extends StatefulWidget {
const LiveRoomPage({super.key});
@override
State<LiveRoomPage> createState() => _LiveRoomPageState();
}
class _LiveRoomPageState extends State<LiveRoomPage> {
final LiveRoomController _liveRoomController = Get.put(LiveRoomController());
MeeduPlayerController? _meeduPlayerController;
@override
void initState() {
super.initState();
_meeduPlayerController = _liveRoomController.meeduPlayerController;
}
@override
Widget build(BuildContext context) {
final double statusBarHeight = MediaQuery.of(context).padding.top;
final videoHeight = MediaQuery.of(context).size.width * 9 / 16;
return Scaffold(
primary: true,
appBar: AppBar(
centerTitle: false,
titleSpacing: 0,
title: Row(
children: [
NetworkImgLayer(
width: 34,
height: 34,
type: 'avatar',
src: _liveRoomController.liveItem.face,
),
const SizedBox(width: 10),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_liveRoomController.liveItem.uname,
style: const TextStyle(fontSize: 14),
),
const SizedBox(height: 3),
Text(_liveRoomController.liveItem.title,
style: const TextStyle(fontSize: 12)),
],
)
],
),
),
body: Stack(
children: [
Positioned(
top: 0,
left: 0,
right: 0,
child: NetworkImgLayer(
type: 'emote',
src: _liveRoomController.cover,
width: Get.size.width,
height: videoHeight + 45,
),
),
Positioned.fill(
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
child: Container(
decoration: BoxDecoration(
color:
Theme.of(context).colorScheme.background.withOpacity(0.1),
),
),
),
),
Scaffold(
backgroundColor: Colors.transparent,
body: Column(
children: [
AspectRatio(
aspectRatio: 16 / 9,
child: MeeduVideoPlayer(
controller: _meeduPlayerController!,
),
),
Container(
color: Theme.of(context).colorScheme.background,
height: 45,
padding: const EdgeInsets.only(left: 12, right: 12),
child: Row(children: [
Text(
_liveRoomController.liveItem.watchedShow['text_large']),
]),
),
],
),
)
],
),
);
}
}