zoukankan      html  css  js  c++  java
  • 第二篇-用Flutter手撸一个抖音国内版,看看有多炫

    前言

    继上一篇使用Flutter开发的抖音国际版 后再次撸一个国内版抖音,大部分功能已完成,主要是Flutter开发APP速度很爽,  先看下图

    项目主要结构介绍

     这次主要的改动在api.dart 及douyin.dart里,国内抖音的api是不同的,另外地址以及实体类也不一样。详细下面介绍.

    抖音的实体类

    主要是讲json转化为实体模型,然后绑定到view 层面,写这个实体类还是很耗费时间的,毕竟得先用爬网知识讲抖音的json拿到,并且根据json反向写实体类.

    这个地址获取到抖音的推荐列表json: https://creator.douyin.com/aweme/v1/creator/data/billboard/?billboard_type=4,绑定第一个Douyin实体,拿到所有抖音的url地址
     
    通过第二个api地址 https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids= 拿到抖音视频所有的json信息并且绑定VideoData实体类
    class Douyin {
      int statusCode;
      String statusMsg;
      List<BillboardData> billboardData;
      Extra extra;
    
      Douyin({this.statusCode, this.statusMsg, this.billboardData, this.extra});
    
      Douyin.fromJson(Map<String, dynamic> json) {
        statusCode = json["status_code"];
        statusMsg = json["status_msg"];
        if (json['billboard_data'] != null) {
          billboardData = new List<BillboardData>();
          json["billboard_data"].forEach((v) {
            billboardData.add(BillboardData.fromJson(v));
          });
        }
        extra = json['extra'] != null ? new Extra.fromJson(json['extra']) : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["status_code"] = this.statusCode;
        data["status_msg"] = this.statusMsg;
        if (this.billboardData != null) {
          data["billboard_data"] =
              this.billboardData.map((v) => v.toJson()).toList();
        }
        data["extra"] = this.extra;
        return data;
      }
    }
    
    class BillboardData {
      String author;
      String imgUrl;
      String link;
      int rank;
      String title;
      String value;
    
      BillboardData(
          {this.author, this.imgUrl, this.link, this.rank, this.title, this.value});
    
      BillboardData.fromJson(Map<String, dynamic> json) {
        this.author = json["author"];
        this.imgUrl = json["img_url"];
        this.link = json["link"];
        this.rank = json["rank"];
        this.title = json["title"];
        this.value = json["value"];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["author"] = this.author;
        data["img_url"] = this.imgUrl;
        data["link"] = this.link;
        data["rank"] = this.rank;
        data["title"] = this.title;
        data["value"] = this.value;
        return data;
      }
    }
    
    class Extra {
      int now;
      Extra({this.now});
    
      Extra.fromJson(Map<String, dynamic> json) {
        now = json["now"];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["now"] = this.now;
        return data;
      }
    }
    
    class VideoData {
      int statusCode;
      List<Itemlist> itemList;
      ExtraData extra;
    
      VideoData.fromJson(Map<String, dynamic> json) {
        this.statusCode = json["status_code"];
        if (json['item_list'] != null) {
          itemList = new List<Itemlist>();
          json['item_list'].forEach((v) {
            itemList.add(new Itemlist.fromJson(v));
          });
        }
        this.extra =
            json["extra"] != null ? new ExtraData.fromJson(json["extra"]) : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["status_code"] = this.statusCode;
        if (this.itemList != null) {
          data['item_list'] = this.itemList.map((v) => v.toJson()).toList();
        }
        if (this.extra != null) {
          data["extra"] = this.extra.toJson();
        }
        return data;
      }
    }
    
    class Itemlist {
      String awemeid;
      String videolabels;
      String labeltoptext;
      int category;
      Author author;
      int duration;
      String promotions;
      int ispreview;
      int createtime;
      List<ChaList> chalist;
      String commentlist;
      int authoruserid;
      String videotext;
      int groupid;
      bool islivereplay;
      ShareInfo shareinfo;
      String position;
      String imageinfos;
      RiskInfos riskinfos;
      String uniqidposition;
      String geofencing;
      Statistics statistics;
      int awemetype;
      Music music;
      List<TextExtra> textExtras;
      Video video;
      String shareurl;
      String desc;
      String longvideo;
    
      Itemlist(
          {this.awemeid,
          this.videolabels,
          this.labeltoptext,
          this.category,
          this.author,
          this.duration,
          this.promotions,
          this.ispreview,
          this.createtime,
          this.chalist,
          this.commentlist,
          this.authoruserid,
          this.videotext,
          this.groupid,
          this.islivereplay,
          this.shareinfo,
          this.position,
          this.imageinfos,
          this.riskinfos,
          this.uniqidposition,
          this.geofencing,
          this.statistics,
          this.awemetype,
          this.music,
          this.textExtras,
          this.video,
          this.shareurl,
          this.desc,
          this.longvideo});
    
      Itemlist.fromJson(Map<String, dynamic> json) {
        this.awemeid = json["aweme_id"];
        this.videolabels = json["video_labels"];
        this.labeltoptext = json["label_top_text"];
        this.category = json["category"];
        this.author =
            json["author"] != null ? new Author.fromJson(json["author"]) : null;
        this.duration = json["duration"];
        this.promotions = json["promotions"];
        this.ispreview = json["is_preview"];
        this.createtime = json["create_time"];
        if (json["cha_list"] != null) {
          this.chalist = new List<ChaList>();
          json["cha_list"].forEach((v) {
            this.chalist.add(new ChaList.fromJson(v));
          });
        }
        this.commentlist = json["comment_list"];
        this.authoruserid = json["author_user_id"];
        this.videotext = json["video_text"];
        this.groupid = json["group_id"];
        this.islivereplay = json["is_live_replay"];
        this.shareinfo = json["share_info"] != null
            ? new ShareInfo.fromJson(json["share_info"])
            : null;
        this.position = json["position"];
        this.imageinfos = json["image_infos"];
        this.riskinfos = json["risk_infos"] != null
            ? new RiskInfos.fromJson(json["risk_infos"])
            : null;
        this.uniqidposition = json["uniqid_position"];
        this.geofencing = json["geofencing"];
        this.statistics = json["statistics"] != null
            ? new Statistics.fromJson(json["statistics"])
            : null;
        this.awemetype = json["aweme_type"];
        this.music =
            json["music"] != null ? new Music.fromJson(json["music"]) : null;
        if (json["text_extra"] != null) {
          this.textExtras = new List<TextExtra>();
          json['text_extra'].forEach((v) {
            textExtras.add(new TextExtra.formJson(v));
          });
        }
        this.video =
            json["video"] != null ? new Video.fromJson(json["video"]) : null;
        this.shareurl = json["share_url"];
        this.desc = json["desc"];
        this.longvideo = json["long_video"];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["aweme_id"] = this.awemeid;
        data["video_labels"] = this.videolabels;
        data["label_top_text"] = this.labeltoptext;
        data["category"] = this.category;
        if (this.author != null) {
          data["author"] = this.author.toJson();
        }
        data["duration"] = this.duration;
        data["promotions"] = this.promotions;
        data["is_preview"] = this.ispreview;
        data["create_time"] = this.createtime;
        if (this.chalist != null) {
          data["cha_list"] = this.chalist.map((e) => e.toJson()).toList();
        }
        data["comment_list"] = this.commentlist;
        data["author_user_id"] = this.authoruserid;
        data["video_text"] = this.videotext;
        data["group_id"] = this.groupid;
        data["is_live_replay"] = this.islivereplay;
        if (this.shareinfo != null) {
          data["share_info"] = this.shareinfo.toJson();
        }
        data["position"] = this.position;
        data["image_infos"] = this.imageinfos;
        if (this.riskinfos != null) {
          data["risk_infos"] = this.riskinfos.toJson();
        }
        data["uniqid_position"] = this.uniqidposition;
        data["geofencing"] = this.geofencing;
        if (this.statistics != null) {
          data["statistics"] = this.statistics.toJson();
        }
        data["aweme_type"] = this.awemetype;
        if (this.music != null) {
          data["music"] = this.music.toJson();
        }
        if (this.textExtras != null) {
          data["text_extra"] = this.textExtras.map((e) => e.toJson()).toList();
        }
        if (this.video != null) {
          data["video"] = this.video.toJson();
        }
        data["share_url"] = this.shareurl;
        data["desc"] = this.desc;
        data["long_video"] = this.longvideo;
        return data;
      }
    }
    
    class TextExtra {
      String hashtagName;
      int hashtagId;
      int start;
      int end;
      int type;
    
      TextExtra(
          {this.hashtagName, this.hashtagId, this.start, this.end, this.type});
    
      TextExtra.formJson(Map<String, dynamic> json) {
        this.hashtagName = json["hashtag_name"];
        this.hashtagId = json["hashtag_id"];
        this.start = json["start"];
        this.end = json["end"];
        this.type = json["type"];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["hashtag_name"] = this.hashtagName;
        data["hashtag_id"] = this.hashtagId;
        data["start"] = this.start;
        data["end"] = this.end;
        data["type"] = this.type;
        return data;
      }
    }
    
    // Author
    class Author {
      String geofencing;
      String uid;
      String shortID;
      String signature;
      AvatarMedium avatarMedium;
      String uniqueId;
      String followersDetail;
      String platformSyncInfo;
      String policyVersion;
      String nickname;
      AvatarLarger avatarlarger;
      AvatarThumb avatarthumb;
    
      Author(
          {this.geofencing,
          this.uid,
          this.shortID,
          this.signature,
          this.avatarMedium,
          this.uniqueId,
          this.followersDetail,
          this.platformSyncInfo,
          this.policyVersion,
          this.nickname,
          this.avatarlarger,
          this.avatarthumb});
    
      Author.fromJson(Map<String, dynamic> json) {
        this.geofencing = json["geofencing"];
        this.uid = json["uid"];
        this.shortID = json["short_id"];
        this.signature = json["signature"];
        this.avatarMedium = json["avatar_medium"] != null
            ? new AvatarMedium.fromJson(json["avatar_medium"])
            : null;
        this.uniqueId = json["unique_id"];
        this.followersDetail = json["followers_detail"];
        this.platformSyncInfo = json["platform_sync_info"];
        this.policyVersion = json["policy_version"];
        this.nickname = json["nickname"];
        this.avatarlarger = json["avatar_larger"] != null
            ? new AvatarLarger.formJson(json["avatar_larger"])
            : null;
        this.avatarthumb = json["avatar_thumb"] != null
            ? new AvatarThumb.formJson(json["avatar_thumb"])
            : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["geofencing"] = this.geofencing;
        data["uid"] = this.uid;
        data["short_id"] = this.shortID;
        data["signature"] = this.signature;
        if (this.avatarMedium != null) {
          data["avatar_medium"] = this.avatarMedium.toJson();
        }
        data["unique_id"] = this.uniqueId;
        data["followers_detail"] = this.followersDetail;
        data["platform_sync_info"] = this.platformSyncInfo;
        data["policy_version"] = this.policyVersion;
        data["nickname"] = this.nickname;
        if (this.avatarlarger != null) {
          data["avatar_larger"] = this.avatarlarger.toJson();
        }
        if (this.avatarthumb != null) {
          data["avatar_thumb"] = this.avatarthumb.toJson();
        }
        return data;
      }
    }
    
    class AvatarMedium {
      List<String> urlList;
      String uri;
      AvatarMedium({this.urlList, this.uri});
    
      AvatarMedium.fromJson(Map<String, dynamic> json) {
        if (json["url_list"] != null) {
          this.urlList = json["url_list"].cast<String>();
        }
        this.uri = json["uri"];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        return data;
      }
    }
    
    class AvatarLarger {
      String uri;
      List<String> urlList;
      AvatarLarger({this.uri, this.urlList});
    
      AvatarLarger.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    
    class AvatarThumb {
      String uri;
      List<String> urlList;
      AvatarThumb({this.uri, this.urlList});
    
      AvatarThumb.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    
    class ExtraData {
      int now;
      String logid;
      ExtraData({this.now, this.logid});
    
      ExtraData.fromJson(Map<String, dynamic> json) {
        this.now = json["now"];
        this.logid = json["logid"];
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["now"] = this.now;
        data["logid"] = this.logid;
        return data;
      }
    }
    //End author
    
    //ChaList
    class ChaList {
      String chaName;
      int viewCount;
      String hashTagProfile;
      bool isCommerce;
      String cid;
      String desc;
      int userCount;
      String connectMusic;
      int type;
      CoverItem coverItem;
      ChaList(
          {this.chaName,
          this.viewCount,
          this.hashTagProfile,
          this.isCommerce,
          this.cid,
          this.desc,
          this.userCount,
          this.connectMusic,
          this.type,
          this.coverItem});
    
      ChaList.fromJson(Map<String, dynamic> json) {
        this.chaName = json["cha_name"];
        this.viewCount = json["view_count"];
        this.hashTagProfile = json["hash_tag_profile"];
        this.isCommerce = json["is_commerce"];
        this.cid = json["cid"];
        this.desc = json["desc"];
        this.userCount = json["user_count"];
        this.connectMusic = json["connect_music"];
        this.type = json["type"];
        this.coverItem = json["cover_item"] != null
            ? new CoverItem.formJson(json["cover_item"])
            : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["cha_name"] = this.chaName;
        data["view_count"] = this.viewCount;
        data["hash_tag_profile"] = this.hashTagProfile;
        data["is_commerce"] = this.isCommerce;
        data["cid"] = this.cid;
        data["desc"] = this.desc;
        data["user_count"] = this.userCount;
        data["connect_music"] = this.connectMusic;
        data["type"] = this.type;
        if (this.coverItem != null) {
          data["cover_item"] = this.coverItem.toJson();
        }
        return data;
      }
    }
    
    class CoverItem {
      String uri;
      List<String> urlList;
      CoverItem({this.uri, this.urlList});
      CoverItem.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    //End ChaList
    
    //ShareInfo
    class ShareInfo {
      String shareweibodesc;
      String sharedesc;
      String sharetitle;
      ShareInfo({this.shareweibodesc, this.sharedesc, this.sharetitle});
      ShareInfo.fromJson(Map<String, dynamic> json) {
        this.shareweibodesc = json["share_weibo_desc"];
        this.sharedesc = json["share_desc"];
        this.sharetitle = json["share_title"];
      }
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["share_weibo_desc"] = this.shareweibodesc;
        data["share_desc"] = this.sharedesc;
        data["share_title"] = this.sharetitle;
        return data;
      }
    }
    //End ShareInfo
    
    //RiskInfos
    class RiskInfos {
      bool warn;
      int type;
      String content;
      RiskInfos({this.warn, this.type, this.content});
      RiskInfos.fromJson(Map<String, dynamic> json) {
        this.warn = json["warn"] as bool;
        this.type = json["type"];
        this.content = json["content"];
      }
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["warn"] = this.warn;
        data["type"] = this.type;
        data["content"] = this.content;
        return data;
      }
    }
    //End RiskInfos
    
    //Statistics
    class Statistics {
      String awemeId;
      int commentCount;
      int diggCount;
      Statistics.fromJson(Map<String, dynamic> json) {
        this.awemeId = json["aweme_id"];
        this.commentCount = json["comment_count"];
        this.diggCount = json["digg_count"];
      }
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["aweme_id"] = this.awemeId;
        data["comment_count"] = this.commentCount;
        data["digg_count"] = this.diggCount;
        return data;
      }
    }
    //End Statistics
    
    //Music
    class Music {
      CoverLarge coverlarge;
      CoverMedium covermedium;
      int duration;
      int status;
      String mid;
      String title;
      String author;
      PlayUrl playurl;
      String position;
      int id;
      CoverHd coverhd;
      CoverThumb coverthumb;
    
      Music.fromJson(Map<String, dynamic> json) {
        this.coverlarge = json["cover_large"] != null
            ? new CoverLarge.formJson(json["cover_large"])
            : null;
        this.covermedium = json["cover_medium"] != null
            ? new CoverMedium.formJson(json["cover_medium"])
            : null;
        this.duration = json["duration"];
        this.status = json["status"];
        this.mid = json["mid"];
        this.title = json["title"];
        this.author = json["author"];
        this.playurl = json["play_url"] != null
            ? new PlayUrl.formJson(json["play_url"])
            : null;
        this.position = json["position"];
        this.id = json["id"];
        this.coverhd = json["cover_hd"] != null
            ? new CoverHd.formJson(json["cover_hd"])
            : null;
        this.coverthumb = json["cover_thumb"] != null
            ? new CoverThumb.formJson(json["cover_thumb"])
            : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        if (this.coverlarge != null) {
          data["cover_large"] = this.coverlarge.toJson();
        }
        if (this.covermedium != null) {
          data["cover_medium"] = this.covermedium.toJson();
        }
        data["duration"] = this.duration;
        data["status"] = this.status;
        data["mid"] = this.mid;
        data["title"] = this.title;
        data["author"] = this.author;
        if (this.playurl != null) {
          data["play_url"] = this.playurl.toJson();
        }
        data["position"] = this.position;
        data["id"] = this.id;
        if (this.coverhd != null) {
          data["cover_hd"] = this.coverhd.toJson();
        }
        if (this.coverthumb != null) {
          data["cover_thumb"] = this.coverthumb.toJson();
        }
        return data;
      }
    }
    
    class CoverLarge {
      String uri;
      List<String> urlList;
      CoverLarge({this.uri, this.urlList});
      CoverLarge.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    
    class CoverMedium {
      String uri;
      List<String> urlList;
      CoverMedium({this.uri, this.urlList});
      CoverMedium.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    
    class PlayUrl {
      String uri;
      List<String> urlList;
      PlayUrl({this.uri, this.urlList});
      PlayUrl.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    
    class CoverHd {
      String uri;
      List<String> urlList;
      CoverHd({this.uri, this.urlList});
      CoverHd.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    
    class CoverThumb {
      String uri;
      List<String> urlList;
      CoverThumb({this.uri, this.urlList});
      CoverThumb.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    //End Music
    
    //Video
    class Video {
      int width;
      OriginCover origincover;
      String ratio;
      bool haswatermark;
      String bitrate;
      PlayAddr playaddr;
      Cover cover;
      int duration;
      String vid;
      int islongvideo;
      int height;
      DynamicCover dynamiccover;
      Video(
          {this.width,
          this.origincover,
          this.ratio,
          this.haswatermark,
          this.bitrate,
          this.playaddr,
          this.cover,
          this.duration,
          this.vid,
          this.islongvideo,
          this.height,
          this.dynamiccover});
      Video.fromJson(Map<String, dynamic> json) {
        this.width = json["width"];
        this.origincover = json["origin_cover"] != null
            ? new OriginCover.formJson(json["origin_cover"])
            : null;
        this.ratio = json["ratio"];
        this.haswatermark = json["has_watermark"];
        this.bitrate = json["bit_rate"];
        this.playaddr = json["play_addr"] != null
            ? new PlayAddr.formJson(json["play_addr"])
            : null;
        this.cover =
            json["cover"] != null ? new Cover.formJson(json["cover"]) : null;
        this.duration = json["duration"];
        this.vid = json["vid"];
        this.islongvideo = json["is_long_video"];
        this.height = json["height"];
        this.dynamiccover = json["dynamic_cover"] != null
            ? new DynamicCover.formJson(json["dynamic_cover"])
            : null;
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["width"] = this.width;
        if (this.origincover != null) {
          data["origin_cover"] = this.origincover.toJson();
        }
        data["ratio"] = this.ratio;
        data["has_watermark"] = this.haswatermark;
        data["bit_rate"] = this.bitrate;
        if (this.playaddr != null) {
          data["play_addr"] = this.playaddr.toJson();
        }
        if (this.cover != null) {
          data["cover"] = this.cover.toJson();
        }
        data["duration"] = this.duration;
        data["vid"] = this.vid;
        data["is_long_video"] = this.islongvideo;
        data["height"] = this.height;
        if (this.dynamiccover != null) {
          data["dynamic_cover"] = this.dynamiccover.toJson();
        }
        return data;
      }
    }
    
    class OriginCover {
      String uri;
      List<String> urlList;
      OriginCover({this.uri, this.urlList});
      OriginCover.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    
    class PlayAddr {
      String uri;
      List<String> urlList;
      PlayAddr({this.uri, this.urlList});
      PlayAddr.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    
    class Cover {
      String uri;
      List<String> urlList;
      Cover({this.uri, this.urlList});
      Cover.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    
    class DynamicCover {
      String uri;
      List<String> urlList;
      DynamicCover({this.uri, this.urlList});
      DynamicCover.formJson(Map<String, dynamic> json) {
        this.uri = json["uri"] as String;
        this.urlList = json["url_list"].cast<String>();
      }
    
      Map<String, dynamic> toJson() {
        final Map<String, dynamic> data = new Map<String, dynamic>();
        data["url_list"] = this.urlList;
        data["uri"] = this.uri;
        return data;
      }
    }
    
    //End Video
    

      

    取抖音无水印视频,这里才是关键

    通过这个api地址 https://aweme.snssdk.com/aweme/v1/play/?video_id={}&ratio=720p&line=0&media_type=4&vr_type=0&improve_bitrate=0&is_play_url=1&h265=1&adapt720=1 可以成功的拿到无水印视频,

    此方法仅用于学习研究目的,不得从事违法活动哈,  否则与本作者无关.

    具体实现代码如下

    import 'dart:io';
    
    import 'package:flutter/cupertino.dart';
    import 'package:http/http.dart' as http;
    import 'package:dio/dio.dart';
    
    class RequestController {
      //static String host = "https://www.tiktok.com/";
      static String host = "https://creator.douyin.com";
      String url = host + "/aweme/v1/creator/data/billboard/?billboard_type=4";
    
      String video =
          "https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=";
    
      String player = "https://aweme.snssdk.com/aweme/v1/play/?video_id=";
    
      Future<String> getVideos() async {
        try {
          var response = await http.get(url);
          return response.body;
        } catch (e) {
          return e.toString();
        }
      }
    
      //获取无水印的视频
      Future<String> getRedirects(String videoid) async {
        try {
          var response = await new Dio().get(
            player +
                videoid +
                "&ratio=720p&line=0&media_type=4&vr_type=0&improve_bitrate=0&is_play_url=1&h265=1&adapt720=1",
            options: Options(
                headers: headers,
                contentType: "text/html; charset=utf-8",
                followRedirects: false,
                validateStatus: (status) {
                  return status < 500;
                }),
          );
          if (response.statusCode == 302) {
            return response.data.toString().split('"')[1];
          }
          return '';
        } catch (ex) {
          return '';
        }
      }
    
      Future<String> getCookie() async {
        try {
          var response = await http.get(host + "/share/item/");
          return response.headers["set-cookie"];
        } catch (e) {
          return "error";
        }
      }
    
      var headers = {
        "user-agent":
            "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"
      };
    }
    

     

    剩下就是改造TrendingScreen里获取视频的方法 

      getTrending() async {
        //var cookies = await api.getCookie();
        //api.setCookie(cookies);
        try {
          var response = await http.get(
            api.url,
            headers: api.headers,
          );
          Douyin tiktok = Douyin.fromJson(jsonDecode(response.body));
          tiktok.billboardData.forEach(
            (item) {
              setState(() {
                getVideos(item);
              });
            },
          );
        } catch (ex) {
          SimpleDialog(
            title: Text('Hot videos list is empty'),
          );
          print(ex);
        }
      }
    

      

    把获取到的无水印视频加载到view层

    getVideos(BillboardData v) async {
        try {
          var url = v.link.split("/")[5];
          var response = await http.get(
            api.video + url + "&dytk",
            headers: api.headers,
          );
          VideoData videoData = VideoData.fromJson(jsonDecode(response.body));
          //获取无水印的视频地址
          api.getRedirects(videoData.itemList[0].video.playaddr.uri).then((url) => {
                print( Uri.decodeFull(url)),
                if (url != '')
                  {
                    videos.add(VideoItem(
                      data: videoData,
                      videourl: url,
                    ))
                  }
              });
        } catch (ex) {
          print(ex);
        }
      }
    

     

    最后,就是绑定视频数据啦,大功告成!

      Widget build(BuildContext context) {
        return Scaffold(
          body: Stack(
            children: <Widget>[
              DouyinVideoPlayer(
                url: videourl,
              ),
              title(),
              VideoDescription(
                description: data.itemList[0].textExtras[0].hashtagName,
                musicName: data.itemList[0].music.title,
                authorName: data.itemList[0].music.author,
                userName: data.itemList[0].author.nickname,
              ),
              ActionsToolbar(
                comments: data.itemList[0].statistics.commentCount.toString(),
                userImg: data.itemList[0].author.avatarMedium.urlList[0],
                favorite: data.itemList[0].statistics.diggCount,
                coverImg: data.itemList[0].music.covermedium.urlList[0],
              ),
            ],
          ),
        );
      }
    

     

    结语

    写到这里,手撸一个抖音app完成了基本功能,一些数据转化比喻点赞数还是原始int数据,需要转化成K M 等,后续待完善,毕竟花了一天时间来写这个app纯粹为了兴趣. 本人也极喜欢玩抖音.

    另外因为写得匆忙,只测试了少量数据,json返回的数据有些为null ,也不知道具体是啥类型,这个待完善。 各位博友们觉得感兴趣的点个赞哈.  支持支持!

    顺便说一下,各位支持的话点赞关注我继续完善剩余的部分,有需要学习了解的可以联系我,代码上传到github ,地址:https://github.com/WangCharlie/douyin,到这里就点个star, 谢谢.

  • 相关阅读:
    面向对象-类
    模块04
    总结
    昨天的新的解决方法
    感冒了~ vs中py和vb实现一个小算法
    vs2015社区版不支持installshield
    网站被黑了
    2018/11/18(python)
    2018/11/14
    2018/11/12(python)
  • 原文地址:https://www.cnblogs.com/fengqingyangNo1/p/12953032.html
Copyright © 2011-2022 走看看