datangyun 11 maanden geleden
commit
11fd459032
1 gewijzigde bestanden met toevoegingen van 604 en 0 verwijderingen
  1. 604 0
      lib/code/live/YSVideoDetail.dart

+ 604 - 0
lib/code/live/YSVideoDetail.dart

@@ -0,0 +1,604 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutterappfuyou/code/base/YSNetWorking.dart';
+import 'package:flutterappfuyou/code/base/YSTools.dart';
+import 'package:video_player/video_player.dart';
+import 'package:wakelock/wakelock.dart';
+
+class YSVideoDetail extends StatefulWidget {
+  final videoId;
+  const YSVideoDetail({Key key, this.videoId}) : super(key: key);
+
+  @override
+  _YSVideoDetailState createState() => _YSVideoDetailState();
+}
+
+class _YSVideoDetailState extends State<YSVideoDetail> {
+  Map _infoDict = {};
+  @override
+  void initState() {
+    Wakelock.enable();
+    Future.delayed(Duration(seconds: 0)).then((value) {
+      _getVideoDetailData();
+    });
+    super.initState();
+  }
+  @override
+  void dispose() {
+    Wakelock.disable();
+    super.dispose();
+  }
+  @override
+  Widget build(BuildContext context) {
+    return AnnotatedRegion<SystemUiOverlayStyle>(
+      value:  SystemUiOverlayStyle.light,
+      child: Scaffold(
+        body: SingleChildScrollView(
+          child: Column(
+            children: [
+              Container(
+                height: MediaQuery.of(context).size.height-50,
+                width: MediaQuery.of(context).size.width,
+                color: Color(0xFFF5F3F0),
+                child: LayoutBuilder(
+                  builder: (BuildContext context, BoxConstraints constraints) {
+                    return Column(
+                      children: [
+                        Stack(
+                          children: [
+                            Container(
+                              height: constraints.maxHeight*0.4,
+                              color: Colors.black,
+                              child: _infoDict.isNotEmpty?YSVideoView(url: _infoDict['url_play'],):Container(),
+                            ),
+                            Container(
+                              child: GestureDetector(
+                                child: Icon(Icons.chevron_left,size: 30,color: Colors.white,),
+                                onTap: (){Navigator.pop(context);},
+                              ),
+                              padding: EdgeInsets.only(top: ysTOP(context)+10,left: 15),
+                            )
+                          ],
+                        ),
+                        Container(
+                          height: constraints.maxHeight*0.1,
+                          alignment: Alignment.centerLeft,
+                          child: Text(_infoDict['title']??'',style: TextStyle(fontSize: 15,color: Color(0xFF3A3A3C)),maxLines: 2,),
+                          padding: EdgeInsets.only(left: 10,right: 10),
+                          decoration: BoxDecoration(
+                            border: Border(bottom: BorderSide(color: Colors.grey,width: 0.1))
+                          ),
+                        ),
+                        Container(
+                          height: constraints.maxHeight*0.05,
+                          padding: EdgeInsets.only(left: 10,right: 10),
+                          decoration: BoxDecoration(
+                            border: Border(bottom: BorderSide(color: Colors.grey.withOpacity(0.1),width: 5))
+                          ),
+                          child: Row(
+                            children: [
+                              Container(
+                                width: (constraints.maxWidth-20)*0.8,
+                                child: Text(_infoDict['created_at']??'',style: TextStyle(fontSize: 12,color: Color(0xFF707070)),maxLines: 1,),
+                              ),
+                              Container(
+                                width: (constraints.maxWidth-20)*0.2,
+                                child: RichText(
+                                  text: TextSpan(
+                                    style: TextStyle(fontSize: 12,color: Color(0xFF707070)),
+                                    children: [
+                                      WidgetSpan(child: Icon(Icons.remove_red_eye_outlined,size: 15,color: Color(0xFF707070))),
+                                      TextSpan(text: ' ${_infoDict['view']??''}')
+                                    ]
+                                  ),
+                                ),
+                                alignment: Alignment.centerRight,
+                              )
+                            ],
+                          ),
+                        ),
+                        Container(
+                          height: constraints.maxHeight*0.05,
+                          alignment: Alignment.centerLeft,
+                          child: Text('${_infoDict['comment_count']??''}条评论',style: TextStyle(fontSize: 12,color: Color(0xFF707070)),maxLines: 1,),
+                          padding: EdgeInsets.only(left: 10,right: 10),
+                          decoration: BoxDecoration(
+                            border: Border(bottom: BorderSide(color: Colors.grey,width: 0.1))
+                          ),
+                        ),
+                        Container(
+                          height: constraints.maxHeight*0.4,
+                          child: YSCommentView(videoId: widget.videoId,),
+                        )
+                      ],
+                    );
+                  },
+                )
+              ),
+              Container(
+                height: 50,
+                color: Colors.white,
+                width: MediaQuery.of(context).size.width,
+                padding: EdgeInsets.only(left: 20,right: 20,top: 10,bottom: 10),
+                child: GestureDetector(
+                  onTap: (){
+                    ysShowBottomAlertView2(context, YSInputView(valueSetter: (value) async{
+                      Map dict = await ysRequestHttp(context, requestType.post, 'train/video/comment', {'video_id':widget.videoId,'body':value});
+                      if(dict!=null){
+                        FocusScope.of(context).unfocus();
+                        refreshKey2.currentState.refresh();
+                      }
+                    },));
+                  },
+                  child: Container(
+                    alignment: Alignment.centerLeft,
+                    padding: EdgeInsets.only(left: 20,right: 20),
+                    child: Text('我来说两句',style: TextStyle(fontSize: 15,color: Color(0xFF707070)),),
+                    decoration: BoxDecoration(
+                      color: Color(0xFFF5F3F0),
+                      borderRadius: BorderRadius.all(Radius.circular(50))
+                    ),
+                  ),
+                ),
+              )
+            ],
+          ),
+        ),
+      ),
+    );
+  }
+  _getVideoDetailData() async{
+    Map dict = await ysRequestHttp(context, requestType.get, 'train/video/info', {'video_id':widget.videoId});
+    if(dict!=null){
+      _infoDict = dict['data'];
+      setState(() {});
+    }
+  }
+}
+
+class YSVideoView extends StatefulWidget {
+  final String url;
+  const YSVideoView({Key key, this.url}) : super(key: key);
+
+  @override
+  _YSVideoViewState createState() => _YSVideoViewState();
+}
+
+class _YSVideoViewState extends State<YSVideoView> {
+  VideoPlayerController _videoPlayerController;
+  StateSetter _progressSet;
+  String _startTime = '00:00:00';
+  String _endTime = '00:00:00';
+  @override
+  void initState() {
+    _videoPlayerController = VideoPlayerController.network(widget.url)
+      ..addListener(() {
+        Duration duration = _videoPlayerController.value.duration;
+        Duration position = _videoPlayerController.value.position;
+        _endTime = '${duration.inHours}'.padLeft(2,'0')+':'+'${duration.inMinutes}'.padLeft(2,'0')+':'+'${duration.inSeconds}'.padLeft(2,'0');
+        _startTime = '${position.inHours}'.padLeft(2,'0')+':'+'${position.inMinutes}'.padLeft(2,'0')+':'+'${position.inSeconds}'.padLeft(2,'0');
+        if(mounted&&_progressSet!=null){
+          _progressSet(() {});
+        }
+      })
+      ..initialize().then((_) {
+        _videoPlayerController.setLooping(true);
+        _videoPlayerController.play();
+        setState(() {});
+      });
+    super.initState();
+  }
+  @override
+  void dispose() {
+    _videoPlayerController.dispose();
+    super.dispose();
+  }
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      child: Stack(
+        children: [
+          _videoPlayerController.value.aspectRatio<1?Center(
+            child: AspectRatio(
+              aspectRatio: _videoPlayerController.value.aspectRatio,
+              child: VideoPlayer(_videoPlayerController,),
+            ),
+          ):VideoPlayer(_videoPlayerController,),
+          _pauseView(controller: _videoPlayerController,),
+          Positioned(
+            left: 10,
+            right: 10,
+            top: (MediaQuery.of(context).size.height-50)*0.4-50,
+            child: StatefulBuilder(
+              builder: (context,progressSet){
+                _progressSet = progressSet;
+                return Container(
+                  child: Row(
+                    children: [
+                      Container(
+                        width: 100,
+                        child: Row(
+                          children: [
+                            GestureDetector(
+                              onTap: (){
+                                progressSet(() {
+                                  _videoPlayerController.value.isPlaying?_videoPlayerController.pause() : _videoPlayerController.play();
+                                });
+                                progressSet(() {});
+                              },
+                              child: Icon(_videoPlayerController.value.isPlaying?Icons.pause:Icons.play_arrow,size: 25,color: Colors.white,),
+                            ),
+                            Container(
+                              alignment: Alignment.center,
+                              width: 75,
+                              child: Text(_startTime,style: TextStyle(fontSize: 10,color: Colors.white),),
+                            )
+                          ],
+                        ),
+                      ),
+                      Container(
+                          width: MediaQuery.of(context).size.width-230,
+                          height:6.5,
+                          child: VideoProgressIndicator(
+                            _videoPlayerController,
+                            allowScrubbing: true,
+                            colors: VideoProgressColors(playedColor: Colors.white,backgroundColor: Colors.black),
+                          )
+                      ),
+                      Container(
+                          width: 100,
+                          child: Row(
+                            children: [
+                              Container(
+                                alignment: Alignment.center,
+                                width: 75,
+                                child: Text(_endTime,style: TextStyle(fontSize: 12,color: Colors.white),),
+                              ),
+                              GestureDetector(
+                                onTap: (){
+                                    Navigator.of(context).push(
+                                      CupertinoPageRoute(builder: (context){
+                                        return YSVideoHorizontal(player: _videoPlayerController,title: '',);
+                                      })
+                                    );
+                                },
+                                child: Image.asset('lib/images/spsx.png',height: 25,width: 25,),
+                              )
+                            ],
+                          )
+                      ),
+                    ],
+                  ),
+                );
+              },
+            )
+          )
+        ],
+      )
+    );
+  }
+
+  _pauseView({VideoPlayerController controller}) {
+    return StatefulBuilder(
+      builder: (context,playSet){
+        return Stack(
+          children: <Widget>[
+            AnimatedSwitcher(
+              duration: Duration(milliseconds: 50),
+              reverseDuration: Duration(milliseconds: 200),
+              child: controller.value.isPlaying? Container():Container(
+                alignment: Alignment.center,
+                color: Colors.transparent,
+                child: Icon(
+                  Icons.play_circle_filled,
+                  color: Colors.white,
+                  size: 50,
+                ),
+              ),
+            ),
+            GestureDetector(
+              onTap: () {
+                playSet(() {
+                  controller.value.isPlaying ? controller.pause() : controller.play();
+                });
+                _progressSet(() {});
+              },
+            ),
+          ],
+        );
+      },
+    );
+  }
+}
+
+
+class YSInputView extends StatefulWidget {
+  final ValueSetter valueSetter;
+  const YSInputView({Key key, this.valueSetter}) : super(key: key);
+
+  @override
+  _YSInputViewState createState() => _YSInputViewState();
+}
+
+class _YSInputViewState extends State<YSInputView> {
+  TextEditingController _editingController = TextEditingController();
+  @override
+  void dispose() {
+    _editingController.dispose();
+    super.dispose();
+  }
+  @override
+  Widget build(BuildContext context) {
+    return Container(
+      height: 50,
+      color: Colors.white,
+      width: MediaQuery.of(context).size.width,
+      padding: EdgeInsets.only(left: 20,right: 20,top: 10,bottom: 10),
+      child: CupertinoTextField(
+        autofocus: true,
+        placeholder: '我来说两句',
+        style: TextStyle(fontSize: 15,color: Color(0xFF707070)),
+        placeholderStyle: TextStyle(fontSize: 15,color: Color(0xFF707070)),
+        padding: EdgeInsets.only(left: 20,right: 20),
+        controller: _editingController,
+        decoration: BoxDecoration(
+          color: Color(0xFFF5F3F0),
+          borderRadius: BorderRadius.all(Radius.circular(50))
+        ),
+        textInputAction: TextInputAction.send,
+        onSubmitted: (value){
+          if(value.isNotEmpty){
+            widget.valueSetter(value);
+            _editingController.text = '';
+            Navigator.pop(context);
+          }
+        },
+      ),
+    );
+  }
+}
+
+
+class YSCommentView extends StatefulWidget {
+  final videoId;
+  const YSCommentView({Key key, this.videoId}) : super(key: key);
+
+  @override
+  _YSCommentViewState createState() => _YSCommentViewState();
+}
+
+class _YSCommentViewState extends State<YSCommentView> {
+  List _commentArray = [];
+  @override
+  Widget build(BuildContext context) {
+    return YSRefreshLoad(
+      key: refreshKey2,
+      dataWidget: SingleChildScrollView(
+        child: ListView.separated(
+          itemBuilder: (context,index){
+            Map item = _commentArray[index];
+            return Container(
+              padding: EdgeInsets.only(top: 10,bottom: 10),
+              child: Row(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Container(
+                    height: 40,
+                    width: 40,
+                    decoration: BoxDecoration(
+                      color: Colors.grey,
+                      borderRadius: BorderRadius.all(Radius.circular(50)),
+                      image: DecorationImage(image: NetworkImage(item['user_avatar']),fit: BoxFit.cover)
+                    ),
+                  ),
+                  Container(
+                    width: MediaQuery.of(context).size.width-60,
+                    padding: EdgeInsets.only(left: 15),
+                    child: Column(
+                      crossAxisAlignment: CrossAxisAlignment.start,
+                      children: [
+                        Text(item['user_simple_name']??'',style: TextStyle(fontSize: 15,color: Color(0xFF3A3A3C),fontWeight: FontWeight.bold),maxLines: 1,),
+                        Container(
+                          padding: EdgeInsets.only(top: 8,bottom: 8),
+                          child: Text(item['body']??'',style: TextStyle(fontSize: 15,color: Color(0xFF707070)),maxLines: 1,),
+                        ),
+                        Text(item['created_at']??'',style: TextStyle(fontSize: 12,color: Color(0xFF707070)),maxLines: 1,),
+                      ],
+                    ),
+                  )
+                ],
+              ),
+            );
+          },
+          separatorBuilder: (context,index){
+            return Divider(color: Colors.grey,height: 0.1,thickness: 0.1,);
+          },
+          itemCount: _commentArray.length,
+          padding: EdgeInsets.only(left: 10,right: 10),
+          shrinkWrap: true,
+          physics: NeverScrollableScrollPhysics(),
+        ),
+      ),
+      url: 'train/video/comment',
+      request: {'video_id':widget.videoId},
+      postData: (value){
+        _commentArray = value;
+        setState(() {});
+      },
+    );
+  }
+}
+
+
+class YSVideoHorizontal extends StatefulWidget {
+  final VideoPlayerController player;
+  final title;
+  const YSVideoHorizontal({Key key, this.player, this.title}) : super(key: key);
+
+  @override
+  _YSVideoHorizontalState createState() => _YSVideoHorizontalState();
+}
+
+class _YSVideoHorizontalState extends State<YSVideoHorizontal> {
+  var _playSet,_progressSet;
+  String _startTime = '00:00:00';
+  String _endTime = '00:00:00';
+  @override
+  void initState() {
+    SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
+    SystemChrome.setPreferredOrientations([
+      DeviceOrientation.landscapeLeft, //全屏时旋转方向,左边
+    ]);
+    widget.player..addListener(() {
+      Duration duration = widget.player.value.duration;
+      Duration position = widget.player.value.position;
+      _endTime = '${duration.inHours}'.padLeft(2,'0')+':'+'${duration.inMinutes}'.padLeft(2,'0')+':'+'${duration.inSeconds}'.padLeft(2,'0');
+      _startTime = '${position.inHours}'.padLeft(2,'0')+':'+'${position.inMinutes}'.padLeft(2,'0')+':'+'${position.inSeconds}'.padLeft(2,'0');
+      if(mounted&&_progressSet!=null){
+        _progressSet(() {});
+      }
+    });
+    super.initState();
+  }
+  @override
+  void dispose() {
+    widget.player..removeListener(() { });
+    SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: SystemUiOverlay.values);
+    SystemChrome.setPreferredOrientations([
+      DeviceOrientation.portraitUp,
+    ]);
+    super.dispose();
+  }
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+      backgroundColor: Colors.black,
+      body: Container(
+        height: MediaQuery.of(context).size.height,
+        width: MediaQuery.of(context).size.width,
+        child: Stack(
+          children: <Widget>[
+            widget.player.value.aspectRatio<1?Center(
+              child: AspectRatio(
+                aspectRatio: widget.player.value.aspectRatio,
+                child: VideoPlayer(widget.player,),
+              ),
+            ):VideoPlayer(widget.player,),
+            _pauseView(controller: widget.player,),
+            Container(
+              width: MediaQuery.of(context).size.width,
+              height: 30,
+              margin: EdgeInsets.only(left: 15,right: 35,top: MediaQuery.of(context).padding.top+10),
+              child: Row(
+                children: [
+                  GestureDetector(
+                    onTap: (){Navigator.pop(context);},
+                    child: Icon(Icons.chevron_left,size: 30,color: Colors.white,),
+                  ),
+                  Container(
+                    width: MediaQuery.of(context).size.width-80,
+                    child: Text('${widget.title}',style: TextStyle(fontSize: 16,color: Colors.white),),
+                  )
+                ],
+              ),
+            ),
+            StatefulBuilder(
+              builder: (context,progressSet){
+                _progressSet = progressSet;
+                return Container(
+                  margin: EdgeInsets.only(top: MediaQuery.of(context).size.height-50,left: 15,right: 15),
+                  child: Row(
+                    children: [
+                      Container(
+                        width: 100,
+                        child: Row(
+                          children: [
+                            GestureDetector(
+                              onTap: (){
+                                _playSet(() {
+                                  widget.player.value.isPlaying?widget.player.pause() : widget.player.play();
+                                });
+                                progressSet(() {});
+                              },
+                              child: Icon(widget.player.value.isPlaying?Icons.pause:Icons.play_arrow,size: 25,color: Colors.white,),
+                            ),
+                            Container(
+                              alignment: Alignment.center,
+                              width: 75,
+                              child: Text(_startTime,style: TextStyle(fontSize: 12,color: Colors.white),),
+                            )
+                          ],
+                        ),
+                      ),
+                      Container(
+                          width: MediaQuery.of(context).size.width-230,
+                          height:6.5,
+                          child: VideoProgressIndicator(
+                            widget.player,
+                            allowScrubbing: true,
+                            colors: VideoProgressColors(playedColor: Colors.white,backgroundColor: Colors.black),
+                          )
+                      ),
+                      Container(
+                          width: 100,
+                          child: Row(
+                            children: [
+                              Container(
+                                alignment: Alignment.center,
+                                width: 75,
+                                child: Text(_endTime,style: TextStyle(fontSize: 12,color: Colors.white),),
+                              ),
+                              GestureDetector(
+                                onTap: (){Navigator.pop(context);},
+                                child: Image.asset('lib/images/spsx.png',height: 25,width: 25,),
+                              )
+                            ],
+                          )
+                      ),
+                    ],
+                  ),
+                );
+              },
+            ),
+          ],
+        ),
+      )
+      ,
+    );
+  }
+
+  _pauseView({VideoPlayerController controller}) {
+    return StatefulBuilder(
+      builder: (context,playSet){
+        _playSet = playSet;
+        return Stack(
+          children: <Widget>[
+            AnimatedSwitcher(
+              duration: Duration(milliseconds: 50),
+              reverseDuration: Duration(milliseconds: 200),
+              child: controller.value.isPlaying? Container():Container(
+                alignment: Alignment.center,
+                color: Colors.transparent,
+                child: Icon(
+                  Icons.play_circle_filled,
+                  color: Colors.white,
+                  size: 50,
+                ),
+              ),
+            ),
+            GestureDetector(
+              onTap: () {
+                playSet(() {
+                  controller.value.isPlaying ? controller.pause() : controller.play();
+                });
+                _progressSet(() {});
+              },
+            ),
+          ],
+        );
+      },
+    );
+  }
+}
+