【问题标题】:Streaming videos from firebase storage in flutter在颤动中从 Firebase 存储流式传输视频
【发布时间】:2019-11-04 21:42:48
【问题描述】:

要在 Flutter 中播放视频,您必须在 init() 方法中实例化其 Url。 那么如何从 Firestore 获取视频 URL 列表? 如果我以 Future 的形式从 Firestore 中检索 Url,那么视频播放器不会接受它,因为它只接受 String 而不是 Future 对象。

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


class VideoScreen extends StatefulWidget {
  VideoScreen({this.studentName});
  final String studentName;
  @override
  _VideoScreenState createState() => _VideoScreenState();
}

class _VideoScreenState extends State<VideoScreen> {

  VideoPlayerController videoPlayerController;
  @override
  void initState() {
   videoPlayerController = VideoPlayerController.network('${getU()}');

    super.initState();
  }


  @override
  Widget build(BuildContext context) {
    final chewieController = ChewieController(
      videoPlayerController: videoPlayerController,
      aspectRatio: 3 / 2,
      autoPlay: true,
      looping: true,
    );
    final playerWidget = Chewie(
      controller: chewieController,
    );
    return playerWidget;
  }
  Future<String> getU() async {
    var document = await Firestore.instance.collection('Students')
        .document('Badri');
    var url = document.get().then((documents) {
      print('video url: ${documents['video']}');
      return documents['video'];
    }
    );
    return url;
  }
}

错误来了 -

W/ykiddypijourna(28557): Accessing hidden method Landroid/media/AudioTrack;->getLatency()I (light greylist, reflection)
I/ExoPlayerImpl(28557): Init 77e7389 [ExoPlayerLib/2.9.6] [beryllium, POCO F1, Xiaomi, 28]
E/ExoPlayerImplInternal(28557): Source error.
E/ExoPlayerImplInternal(28557): com.google.android.exoplayer2.upstream.HttpDataSource$HttpDataSourceException: Unable to connect to Instance of 'Future<String>'
E/ExoPlayerImplInternal(28557):     at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:281)
E/ExoPlayerImplInternal(28557):     at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
E/ExoPlayerImplInternal(28557):     at com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:885)
E/ExoPlayerImplInternal(28557):     at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:381)
E/ExoPlayerImplInternal(28557):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/ExoPlayerImplInternal(28557):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/ExoPlayerImplInternal(28557):     at java.lang.Thread.run(Thread.java:764)
E/ExoPlayerImplInternal(28557): Caused by: java.net.MalformedURLException: no protocol: Instance of 'Future<String>'
E/ExoPlayerImplInternal(28557):     at java.net.URL.<init>(URL.java:601)
E/ExoPlayerImplInternal(28557):     at java.net.URL.<init>(URL.java:498)
E/ExoPlayerImplInternal(28557):     at java.net.URL.<init>(URL.java:447)
E/ExoPlayerImplInternal(28557):     at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.makeConnection(DefaultHttpDataSource.java:426)
E/ExoPlayerImplInternal(28557):     at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:279)
E/ExoPlayerImplInternal(28557):     ... 6 more

【问题讨论】:

  • 出现错误,Url 必须是字符串而不是 Future
  • 请编辑您的问题以包含所有相关信息,包括确切的错误消息,以及它来自哪一行。
  • 你尝试将 Future 传递给网络方法,getU 是返回 Future 而不是字符串

标签: firebase flutter firebase-storage


【解决方案1】:

你写getU 的方式在我看来有点奇怪。你可以试试这个吗?

Future<String> getU() async {
  var docRef = Firestore.instance.collection('Students').document('Badri');
  var doc = await docRef.get();
  return doc['video'];
}

变化:

  • 在创建对文档的引用时无需await。这是一个同步操作,因为那里还没有读取数据。
  • 我在调用get() 时使用await 来解开Future

【讨论】:

  • 我已经实现了你所说的,但错误仍然存​​在。我把错误放在我的答案中。
  • 对不起,它没有指定错误所在的行
【解决方案2】:

回答您的问题可能为时已晚,但有一个非常简单的解决方案。我已经为我即将推出的网站制作了一个页面,其中存储了一堆视频。我已经修改了这里的代码,让它使用视频播放器而不是 iFrame,并且我已经删除了很多无用的东西,比如 appBar 和抽屉

import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:xspectre/Community.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:xspectre/Squad.dart';
import 'package:xspectre/T&C.dart';

import 'AddVideos.dart';
import 'Home.dart';
import 'JoinUs.dart';
import 'Profile.dart';
import 'help/IsPhone.dart';
class VideoPage extends StatefulWidget {
  @override
  _VideoPageState createState() => _VideoPageState();
}
List<Widget> WidgetList = [Center(child:CircularProgressIndicator(),)];

class _VideoPageState extends State<VideoPage> {
  String creator ='';
  String videos = '';
  String game = '';
  final _scrollController = ScrollController();

  @override
  void initState(){
    super.initState();
    makeWidgetList();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        child: Scrollbar(
          controller: _scrollController,
          isAlwaysShown: true,
          child: SingleChildScrollView(
            controller: _scrollController,
            child: Column(
              children: WidgetList
            ),
          ),
        ),
      );
  }
  void makeWidgetList() async{

    Firestore.instance.collection("Videos").getDocuments().then((querySnapshot){
      WidgetList = [];
      List<Widget> RowWidgetList = [];
      int count = 1;
      var result;
      for (result in querySnapshot.documents) {
        if(true) {
          if (isLaptop(context)) {
            WidgetList.add(SizedBox(height: 20));
            RowWidgetList.add(
              Container(
                  height: 200,
                  width: MediaQuery
                      .of(context)
                      .size
                      .width * 0.3,
                  child: videoBox(result['Link'])
              ),
            );
            if (count < 3) {
              count += 1;
            }
            else {
              WidgetList.add(Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: RowWidgetList,
              ));
              WidgetList.add(SizedBox(height: 25.0,));
              RowWidgetList = [];
              count = 1;
              setState(() {});
            }
          }
          else{
            WidgetList.add(
              Container(
                  height: 200,
                  width: MediaQuery
                      .of(context)
                      .size
                      .width * 0.96,
                  child: videoBox(result['Link'])
              ),
            );
            WidgetList.add(
              SizedBox(height:20)
            );
          }
        }
      }
      setState(() {
      });
    });
  }

}
class videoBox extends StatefulWidget {
  String Video;
  videoBox(this.Video);
  @override
  _videoBoxState createState() => _videoBoxState(Video);
}

class _videoBoxState extends State<videoBox> {
  String Video;
  VideoPlayerController videoPlayerController;
  ChewieController chewieController;
  _videoBoxState(this.Video);
  Video
  @override
  void initState(){
     super.initState();
     videoPlayerController = VideoPlayerController.network(Video);
    final chewieController = ChewieController(
      videoPlayerController: videoPlayerController,
      aspectRatio: 3 / 2,
      autoPlay: true,
      looping: true,
      autoInitialize:true
    );
        
  }
  @override
  Widget build(BuildContext context) {
    return Container(
          child: Chewie(
             controller:chewieController,
        ),
    ) ;
  }
}
String type1 = '';
String platform = '';

@FrankVanPuffelen 犯的错误是他使用 getU 函数返回一个未来的字符串,这当然会导致问题。我们需要使用另一种聪明的策略。您可以使用它来创建它。您可以在https://xspectre-9a3b3.web.app/#/ 查看我的版本,然后观看视频。我没有发布完整的代码,但给出了你需要的东西

【讨论】:

    猜你喜欢
    • 2018-01-13
    • 2013-11-08
    • 2017-05-09
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-18
    相关资源
    最近更新 更多