如何在Flutter中的Global Scope中下载视频

时间:2019-12-13 17:53:00

标签: flutter download scope navigation state

我有一个Flutter应用,它显示了网络视频文件的视频列表视图。

我有一个功能 downloadFile(),该功能可将每个视频下载到本地存储,并使用下载文件的信息更新共享的首选项。

这一切都很好,但是,当我使用BottomNavigationBar导航到应用程序中的另一个页面时,我的下载过程中断了,所有信息都丢失了。

我知道这是因为所有下载逻辑都处于VideoListPage状态。

我怎样才能使下载在全局类中进行?我是否需要使用状态管理系统,还是有一种更简便的方法来不丢失下载文件的状态?

谢谢..

main_scafold.dart

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'video_list_page.dart';
import 'podcasts.dart';
import 'my_experience.dart';

//this page is the homescreen

class MainScafold extends StatefulWidget {
  static const String id = 'video_list';

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

class MainScafoldState extends State<MainScafold> {
  int _selectedIndex = 0;
  static const TextStyle optionStyle =
      TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
  List<Widget> _widgetOptions = <Widget>[
    VideoListPage(),
    Podcasts(),
    MyExperience(),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('News'),
      ),
      body: Center(
        child: _widgetOptions.elementAt(_selectedIndex),
      ),
      bottomNavigationBar: BottomNavigationBar(
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            title: Text('Home'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            title: Text('Business'),
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            title: Text('School'),
          ),
        ],
        currentIndex: _selectedIndex,
        selectedItemColor: Colors.amber[800],
        onTap: _onItemTapped,
      ),
    );
  }
}

video_list.dart

import 'dart:convert';
import 'package:networking_demo/models/download_video.dart';
import 'dart:io';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter/material.dart';
import 'package:networking_demo/screens/video_player.dart';
import 'package:networking_demo/models/newsArticle.dart';
import 'package:networking_demo/models/blog_json.dart';
import 'package:http/http.dart' as http;
import 'series_index.dart';
import 'package:networking_demo/models/all_videos.dart';
import 'package:networking_demo/models/single_video.dart';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
import 'package:percent_indicator/percent_indicator.dart';

// This is the screen for all the episodes of Presenter
class VideoListPage extends StatefulWidget {
  @override
  _VideoListPageState createState() => _VideoListPageState();
}

class _VideoListPageState extends State<VideoListPage> {
  bool result = false;
  List<NewsArticle> _newsArticles = List<NewsArticle>();
  List<Datum> _blogs = List<Datum>();

  List<DatumVideo> _videos = List<DatumVideo>();

  double downloadPercent = 0;

  bool downloading = false;
  //var progressString = "";

  Future<void> downloadFile(
      {int currentIndex, title, description, image, videoKey}) async {
    final prefs = await SharedPreferences.getInstance();

    Dio dio = Dio();
    String downloadURL;

    var dir = await getApplicationDocumentsDirectory();
    var localURL = dir.path + '/$videoKey.mp4';
    print('the directory is: ${dir.path}');
    print('the local url is: $localURL');

    try {
      await http
          .get('https://platform.seebenow.com/v1/videos/${videoKey}', headers: {
        "Brand-ID": "2",
        HttpHeaders.authorizationHeader:
            "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjIzMTljMWZlMTk4YzM4NTg5ZDJlMjJlYWM5MGZiMDAwZDdiNDZlZWUxMmVkYjcyMWJiZWI0ZDliMDU1ZTA2NjIyOGI2Njc4YTBmMjA3ZGQyIn0.eyJhdWQiOiIyIiwianRpIjoiMjMxOWMxZmUxOThjMzg1ODlkMmUyMmVhYzkwZmIwMDBkN2I0NmVlZTEyZWRiNzIxYmJlYjRkOWIwNTVlMDY2MjI4YjY2NzhhMGYyMDdkZDIiLCJpYXQiOjE1NzQzNjExOTgsIm5iZiI6MTU3NDM2MTE5OCwiZXhwIjoxNjA1OTgzNTk4LCJzdWIiOiIyNDgyMCIsInNjb3BlcyI6W119.bmNtFzdkld680ADMsohupkETnSh5H03a3sFjYCwiBAipRJrc0FxGAyqNdrpvMUcMMQaqoEEGIDvmfUYdSMknsLVo5AzSQygFTHXQH31BX43JAjcAm3BVGZLueTouNVAstY1C0PIEZ7POxhUEeRNMPEb5zZ8WrNWw7c8YEv1QqcoM13p5zljd7ryxzMxXzF5BaEQr5CDzjWFmXeR-WTyqYmzsXL83s_ESQ1TqetShZD1hahdZnAYpoXsJNU3AnPgPL5zELWtmsJyV4dWqq0GCdQ6dnIaP-livG4KZG-8xR2PYOgjXRkJu2avBtvmqSm7oQQFQa9svqba2YVKiBpSrrVPYKucGepKavTjAeIGrb96OuhB0aToV0RZv7tvgB2A1LLZRLIMHC4zvjhfoqTyEMwMCWCiT7MAi4ODN5kY6DVUOp35YSBVKGkF3Q6aV0NLmWSUbdW3yT5QHTnoVWmTm3EAKRR-lguvGZRzhACjyJEavZ-LXqqE7ay-LwjbeIcq8FFg2UtEyQ5V2ltXwpKVcXEs8zHsvJZFFS6_oNsBg08kTQNrFcrlpm6NzyCG-_-bXr9AtW3DqtThlCE45T3kieFtupDSwli2IIaE8fucd45cfAtwBQVOYgeuwdqG1-ZpxuahjgvG6qxuGFfEDWyFyeed2QI6pbTzoBzL6WJ7zYHs"
      }).then((response) {
        downloadURL = videoFromJson(response.body).data.episodes[0].downloadUrl;
      });

      await dio.download(downloadURL, "${dir.path}/$videoKey.mp4",
          onReceiveProgress: (rec, total) {
        setState(() {
          downloading = true;
          _videos[currentIndex].videoProgress = (rec / total);
          _videos[currentIndex].currentVisible = true;
          // DownloadVideo['']
          print(_videos[currentIndex].videoProgress.toString());
        });
      });
    } catch (e) {
      print(e);
    }

    print('the preferences is' + prefs.containsKey('videos').toString());
    if (!prefs.containsKey('videos')) prefs.setString('videos', '');

    print('localURL $localURL title $title videoKey $videoKey image $image');
    String videoJson = prefs.getString('videos');
    List<DownloadVideo> videoList;
    print('is videos json empty? ${videoJson.isEmpty}');
    if (videoJson.isEmpty) {
      videoList = [];
    } else {
      videoList = downloadVideoFromJson(videoJson);
      // print('this is the video list ${videoList.}');
    }

    videoList.add(
      DownloadVideo(
        title: title,
        description: description,
        videoKey: videoKey,
        image: image,
        localURL: localURL,
      ),
    );
    prefs.setString('videos', jsonEncode(videoList));

    setState(() {
      downloading = false;
    });
    print("Download completed");
  }

  void addInfo() async {
    final prefs = await SharedPreferences.getInstance();
    //print(prefs.containsKey('videos'));
    String videoJson = prefs.getString('videos');
    prefs.setString('videos', '');
    print(
        'the video preferences is empty ${prefs.getString('videos').isEmpty}');
    print(videoJson);
  }

  void _fetchVideos() {
    http.get('https://platform.seebenow.com/v1/episodes/search?type=video',
        headers: {"Brand-ID": "2"}).then((response) {
      setState(() {
        _videos = videosFromJson(response.body).data;
        print(_videos[0].title);
        result = true;
      });
    });
  }

  void _fetchBlogs() {
    http.get('https://platform.seebenow.com/v1/blogs?page=1',
        headers: {"Brand-ID": "2"}).then((response) {
      setState(() {
        _blogs = blogFromJson(response.body).data;
        print(_blogs[0].content.toString());
      });
    });
  }

  @override
  void initState() {
    super.initState();
    _fetchVideos();
    _fetchBlogs();
  }

  Widget _buildBlog(BuildContext context, int index) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Row(
        children: <Widget>[
          Container(
            decoration: BoxDecoration(
              color: Colors.white,
              borderRadius: BorderRadius.circular(20),
            ),
            padding: EdgeInsets.all(10.0),
            width: 250.0,
            height: 80,
            child: Text(
              '"' + _blogs[index].content + ' " ',
              style: TextStyle(fontSize: 13),
            ),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        children: <Widget>[
          Flexible(
            flex: 1,
            child: Container(
              color: Colors.grey.shade300,
              child: ListView.builder(
                scrollDirection: Axis.horizontal,
                itemCount: _blogs.length,
                itemBuilder: _buildBlog,
              ),
            ),
          ),
          Flexible(
            flex: 5,
            child: DefaultTabController(
              length: 2,
              child: Column(
                children: <Widget>[
                  Container(
                    color: Colors.green,
                    child: TabBar(
                      tabs: [
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Text('Episodes'),
                            Tab(
                              icon: Icon(Icons.directions_car),
                            ),
                          ],
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: <Widget>[
                            Text('Series'),
                            Tab(
                              icon: Icon(Icons.directions_car),
                            ),
                          ],
                        ),
                      ],
                    ),
                  ),
                  Expanded(
                    child: Container(
                      color: Colors.lightBlueAccent,
                      child: TabBarView(
                        children: [
                          BuildVideoList(),
                          SeriesIndex(),
                        ],
                      ),
                    ),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  }

  Container BuildVideoList() {
    if (result == false) {
      return Container(
        child: Center(
          child: SizedBox(
            child: CircularProgressIndicator(),
            height: 50.0,
            width: 50.0,
          ),
        ),
      );
    }

    return Container(
      color: Colors.grey.shade300,
      child: ListView.builder(
        itemCount: _videos.length,
        itemBuilder: _buildItemsForListView,
      ),
    );
  }

  Widget _buildItemsForListView(BuildContext context, int index) {
    var progressVariable = _videos[index].videoProgress.toString();

    var downloadText = Text('Download $progressVariable');
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        children: <Widget>[
          FlatButton(
            onPressed: () {
              Navigator.push(context,
                  MaterialPageRoute<void>(builder: (context) {
                return HitomiVideoPlayer(
                    videoKey: _videos[index].videoId,
                    title: _videos[index].title);
              }));
            },
            child: Stack(
              children: <Widget>[
                Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Image.network(_videos[index].image),
                ),
                Padding(
                  padding: const EdgeInsets.only(top: 60),
                  child: Center(
                    child: Align(
                      alignment: Alignment.bottomCenter,
                      child: Visibility(
                        visible: _videos[index].currentVisible,
                        child: CircularPercentIndicator(
                          radius: 50.0,
                          lineWidth: 6.0,
                          animation: false,
                          percent: _videos[index].videoProgress,
                          center: new Text(
                            (_videos[index].videoProgress * 100)
                                .toStringAsFixed(0),
                            style: new TextStyle(
                                fontWeight: FontWeight.bold, fontSize: 12.0),
                          ),
                          circularStrokeCap: CircularStrokeCap.round,
                          progressColor: Colors.red,
                        ),
                      ),
                    ),
                  ),
                ),
              ],
            ),
          ),
          Text(_videos[index].title, style: TextStyle(fontSize: 18)),
          Padding(
            padding: const EdgeInsets.all(12.0),
            child: Text(_videos[index].description,
                style: TextStyle(fontSize: 12)),
          ),
          FlatButton(
            onPressed: () {
              downloadFile(
                  title: _videos[index].title,
                  description: _videos[index].description,
                  image: _videos[index].image,
                  videoKey: _videos[index].videoId,
                  currentIndex: index);
            },
            child: downloadText,
          ),
          FlatButton(
            onPressed: () {
              addInfo();
            },
            child: Text('Add Info'),
          )
        ],
      ),
    );
  }
}

0 个答案:

没有答案