Skip to content

Commit

Permalink
国内抖音app版本更新
Browse files Browse the repository at this point in the history
  • Loading branch information
telsav committed May 27, 2020
1 parent 2e0c2a9 commit 2226b69
Show file tree
Hide file tree
Showing 19 changed files with 2,323 additions and 419 deletions.
31 changes: 31 additions & 0 deletions flutter_app_cn/lib/Screens/homeScreen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:flutter/material.dart';
import 'package:flutter_desktop/Screens/trendingScreen.dart';
import 'package:flutter_desktop/widgets/bottom_toolbar.dart';

class Home extends StatefulWidget {
@override
HomeState createState() => HomeState();
}

class HomeState extends State<Home> {
int currentIndex = 0;
PageController pageController;

@override
Widget build(BuildContext context) {
return Scaffold(
body: PageView(
controller: pageController,
children: <Widget>[
Trending(),
],
onPageChanged: (int index) {
setState(() {
currentIndex = index;
});
},
),
bottomNavigationBar: bottomItems(currentIndex, pageController),
);
}
}
99 changes: 99 additions & 0 deletions flutter_app_cn/lib/Screens/trendingScreen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:getflutter/getflutter.dart';
import 'package:flutter_desktop/config/api.dart';
import 'package:flutter_desktop/models/Douyin.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_desktop/Screens/videoScreen.dart';

class Trending extends StatefulWidget {
_TrendingState createState() => _TrendingState();
}

class _TrendingState extends State<Trending> {
PageController pageController;
BuildContext context;
RequestController api = RequestController();
List<Widget> videos = [];

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);
print(item.toJson());
});
},
);
} catch (ex) {
SimpleDialog(
title: Text('Hot videos list is empty'),
);
print(ex);
}
}

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) => {
url = url.replaceAll('&amp;', '&'),
if (url != '')
{
videos.add(VideoItem(
data: videoData,
videourl: url,
)),
print(url),
}
});
} catch (ex) {
print(ex);
}
}

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

@override
Widget build(BuildContext context) {
context = context;
return PageView(
scrollDirection: Axis.vertical,
controller: pageController,
children: videos.length == 0
? <Widget>[
Container(
color: Colors.black,
child: Center(
child: GFLoader(
type: GFLoaderType.circle,
loaderColorOne: Colors.blueAccent,
loaderColorTwo: Colors.white,
loaderColorThree: Colors.pink,
),
),
)
]
: videos,
);
}
}
48 changes: 48 additions & 0 deletions flutter_app_cn/lib/Screens/videoScreen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:flutter_desktop/models/Douyin.dart';
import 'package:flutter_desktop/widgets/video_description.dart';
import 'package:flutter_desktop/widgets/actions_toolbar.dart';
import 'package:flutter_desktop/widgets/player.dart';

class VideoItem extends StatelessWidget {
final VideoData data;
final String videourl;
const VideoItem({@required this.data,this.videourl});

@override
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],
),
],
),
);
}

Widget title() => Align(
alignment: Alignment.topCenter,
child: Padding(
padding: EdgeInsets.symmetric(vertical: 28.0),
child: Text(
"Trending | For You",
style: TextStyle(color: Colors.white, fontSize: 19.0),
),
),
);
}
61 changes: 61 additions & 0 deletions flutter_app_cn/lib/common/custom_proxy.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'custom_proxy_http_override.dart';

/// Allows you to set and enable a proxy for your app
class CustomProxy {
/// A string representing an IP address for the proxy server
final String ipAddress;

/// The port number for the proxy server
/// Can be null if port is default.
final int port;

/// Set this to true
/// - Warning: Setting this to true in production apps can be dangerous. Use with care!
bool allowBadCertificates;

/// Initializer
CustomProxy(
{@required this.ipAddress, this.port, this.allowBadCertificates = false});

/// Initializer from string
/// Note: Uses static method, rather than named init to allow final properties.
static CustomProxy fromString({@required String proxy}) {
// Check if valid
if (proxy == null || proxy == "") {
assert(
false, "Proxy string passed to CustomProxy.fromString() is invalid.");
return null;
}

// Build and return
final proxyParts = proxy.split(":");
final _ipAddress = proxyParts[0];
final _port = proxyParts.length > 0 ? int.tryParse(proxyParts[1]) : null;
return CustomProxy(
ipAddress: _ipAddress,
port: _port,
);
}

/// Enable the proxy
void enable() {
HttpOverrides.global =
new CustomProxyHttpOverride.withProxy(this.toString());
}

/// Disable the proxy
void disable() {
HttpOverrides.global = null;
}

@override
String toString() {
String _proxy = this.ipAddress;
if (this.port != null) {
_proxy += ":" + this.port.toString();
}
return _proxy;
}
}
32 changes: 32 additions & 0 deletions flutter_app_cn/lib/common/custom_proxy_http_override.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import 'dart:io';

/// This class overrides the global proxy settings.
class CustomProxyHttpOverride extends HttpOverrides {
/// The entire proxy server
/// Format: "localhost:8888"
final String proxyString;

/// Set this to true
/// - Warning: Setting this to true in production apps can be dangerous. Use with care!
final bool allowBadCertificates;

/// Initializer
CustomProxyHttpOverride.withProxy(
this.proxyString, {
this.allowBadCertificates = false,
});

/// Override HTTP client creation
@override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..findProxy = (uri) {
assert(this.proxyString != null && this.proxyString.isNotEmpty,
'You must set a valid proxy if you enable it!');
return "PROXY " + this.proxyString + ";";
}
..badCertificateCallback = this.allowBadCertificates
? (X509Certificate cert, String host, int port) => true
: null;
}
}
17 changes: 17 additions & 0 deletions flutter_app_cn/lib/common/icons.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:flutter/widgets.dart';

class DouyinIcons {
DouyinIcons._();

static const _kFontFam = 'DouyinIcons';
static const IconData chat_bubble =
const IconData(0xe808, fontFamily: _kFontFam);
static const IconData create = const IconData(0xe809, fontFamily: _kFontFam);
static const IconData heart = const IconData(0xe80a, fontFamily: _kFontFam);
static const IconData home = const IconData(0xe80b, fontFamily: _kFontFam);
static const IconData messages =
const IconData(0xe80c, fontFamily: _kFontFam);
static const IconData profile = const IconData(0xe80d, fontFamily: _kFontFam);
static const IconData reply = const IconData(0xe80e, fontFamily: _kFontFam);
static const IconData search = const IconData(0xe80f, fontFamily: _kFontFam);
}
62 changes: 62 additions & 0 deletions flutter_app_cn/lib/config/api.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
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"
};
}
Loading

0 comments on commit 2226b69

Please sign in to comment.