1

我正在尝试从图库中获取视频,并希望在网格视图和容器内部显示它们,然后在保存按钮上想要将其上传到 firebase firestore。首先,我无法从图库中获取视频并将其显示在 UI 中。我已经看过很多例子并遵循了它们,但它对我不起作用,因为我对这一切都是新手,无法将它放在一起,它需要放在哪里......请帮助我。提前致谢。虽然完整的代码可能与我的查询相关,也可能不相关,但它可能会帮助那些试图实现相同目标的人。这是具有播放按钮、带指示器的视频长度的完整代码。我想我在这里遗漏了一些东西:-

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

}

 @override
void dispose() {
_controller.dispose();
super.dispose();
 }

这是我要显示视频的地方:-

   Container(
              height: MediaQuery.of(context).size.height,
              padding: EdgeInsets.all(20),
              child:GridView.builder(
                  itemCount: _video.length,
                  gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                    maxCrossAxisExtent: 150,
                    mainAxisSpacing: 10,
                    crossAxisSpacing: 10,
                  ),
                  itemBuilder: (context,index){
                    return Container(
                      child: _controller.value.isInitialized ?
                      Stack(
                         children: [
                          VideoPlayer(_controller),
                          _ControlsOverlay(_controller),

                        ],
                      )
                          :Container(),
                    );
                  }
              ),

            ),

这是我打开画廊并选择视频的地方;-

 chooseVideo() async {
final pickedVideo = await picker.getVideo(
    source: ImageSource.gallery,
    maxDuration: const Duration(seconds: 60)
);

setState(() {
  _video.add(File(pickedVideo?.path));
  _controller = VideoPlayerController.file(File(_video.toString()));
});
if (pickedVideo.path == null) retrieveLostData();
  }

 Future<void> retrieveLostData() async {
  final LostData response = await     picker.getLostData();
if (response.isEmpty) {
  return;
}
if (response.file != null) {
  setState(() {
    _video.add(File(response.file.path));
  });
} else {
  print(response.file);
}
 } 

这是完整的代码:-

class AddVideo extends StatefulWidget {

@override
_AddVideo createState() => _AddVideo();
}

class _AddVideo extends State<AddVideo> {
 bool uploading = false;
double val = 0;
 CollectionReference imgRef;
firebase_storage.Reference ref;

 List<File> _video = [];
 File videoFile;

 List<String> urls = [];
 final picker = ImagePicker();
 final auth = FirebaseAuth.instance;
 final _stoarge = FirebaseStorage.instance;

 VideoPlayerController _controller;


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

 }


 @override
 void dispose() {
  _controller.dispose();
  super.dispose();
  }


@override
Widget build(BuildContext context) {
return Scaffold(
  extendBodyBehindAppBar: true,

  appBar: AppBar(
    elevation: 0,
    backgroundColor: Colors.transparent,
    actions: [
      ElevatedButton(
        child: Text("SAVE", style: TextStyle(fontSize: 15)),
        onPressed: () {
          setState(() {
            uploading = true;
          });
          _uploadVideo().whenComplete(() => Navigator.of(context).pop());
        },
        style: ElevatedButton.styleFrom(
            padding: EdgeInsets.fromLTRB(25.0, 15.0, 25.0, 10.0),
            shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(30.0))),
      ),
    ],
  ),

  body: Container(
    child: SafeArea(
      child: SingleChildScrollView(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.start,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [

           Container(
             // padding: EdgeInsets.all(20),
              child: ElevatedButton(
                child: Text("Open Gallery", style: TextStyle(fontSize: 20)),
                onPressed: () => !uploading ? chooseVideo() : null,
                style: ElevatedButton.styleFrom(
                    padding: EdgeInsets.fromLTRB(25.0, 15.0, 25.0, 10.0),
                    shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(30.0))),


              ),
            ),

            Container(
              height: MediaQuery.of(context).size.height,
              padding: EdgeInsets.all(20),
              child:GridView.builder(
                  itemCount: _video.length,
                  gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
                    maxCrossAxisExtent: 150,
                    mainAxisSpacing: 10,
                    crossAxisSpacing: 10,
                  ),
                  itemBuilder: (context,index){
                    return Container(
                      child: _controller.value.isInitialized ?
                      Stack(
                         children: [
                          VideoPlayer(_controller),
                          _ControlsOverlay(_controller),

                        ],
                      )
                          :Container(),
                    );
                  }
              ),

            ),
            uploading ?
            Center(
                child: Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    Container(
                      child: Text(
                        'uploading...',
                        style: TextStyle(fontSize: 20),
                      ),
                    ),
                    SizedBox(
                      height: 10,
                    ),
                    CircularProgressIndicator(
                      value: val,
                      valueColor: AlwaysStoppedAnimation<Color>(Colors.green),
                    )
                  ],
                )
            )
                : Container(),
          ],
        ),
      ),
    ),
  ),

  );

  }



  chooseVideo() async {
  final pickedVideo = await picker.getVideo(
    source: ImageSource.gallery,
    maxDuration: const Duration(seconds: 60)
);

setState(() {
  _video.add(File(pickedVideo?.path));
  _controller = VideoPlayerController.file(File(_video.toString()));
});
if (pickedVideo.path == null) retrieveLostData();
 }

 Future<void> retrieveLostData() async {
final LostData response = await picker.getLostData();
if (response.isEmpty) {
  return;
}
if (response.file != null) {
  setState(() {
    _video.add(File(response.file.path));
  });
} else {
  print(response.file);
}
 }

 _uploadVideo() async {
for (var video in _video) {
  var _ref = _stoarge.ref().child("videos/" + Path.basename(video.path));
  await _ref.putFile(video);
  String url = await _ref.getDownloadURL();

  print(url);
  urls.add(url);
  print(url);
}
print("uploading:" + urls.asMap().toString());
await FirebaseFirestore.instance
    .collection("users")
    .doc(auth.currentUser.uid)
    .update({"images": urls});
//  .doc(auth.currentUser.uid).update({"images": FieldValue.arrayUnion(urls) });
   }

 }

 class _ControlsOverlay extends StatelessWidget {
 String getPosition() {
   final duration = Duration(
      milliseconds: controller.value.position.inMilliseconds.round());

  return [duration.inMinutes, duration.inSeconds]
    .map((seg) => seg.remainder(60).toString().padLeft(2, '0'))
    .join(':');
 }

 const _ControlsOverlay(this.controller);

final VideoPlayerController controller;

  @override
 Widget build(BuildContext context) {
return Stack(
  children: <Widget>[
    AnimatedSwitcher(
      duration: Duration(milliseconds: 50),
      reverseDuration: Duration(milliseconds: 200),
      child: controller.value.isPlaying
          ? SizedBox.shrink()
          : Container(
        color: Colors.black26,
        child: Center(
          child: Icon(
            Icons.play_arrow,
            color: Colors.white,
            size: 100.0,
          ),
        ),
      ),
    ),
    GestureDetector(
      onTap: () {
        controller.value.isPlaying ? controller.pause() : controller.play();
      },
    ),
    Positioned(
        bottom: 0,
        left: 0,
        right: 0,
        child: Row(
          children: [
            const SizedBox(width: 8),
            Expanded(child: Text(getPosition()),),
            const SizedBox(width: 8),
            Expanded(child: buildIndicator()),
            const SizedBox(width: 8),

          ],
        )
    ),

  ],
);
  }

 Widget buildIndicator() => Container(
margin: EdgeInsets.all(8).copyWith(right: 0),
height: 10,
child: VideoProgressIndicator(
  controller, allowScrubbing: true,
),
  );

 }   
4

0 回答 0