-
Notifications
You must be signed in to change notification settings - Fork 132
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
2,323 additions
and
419 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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), | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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('&', '&'), | ||
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, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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), | ||
), | ||
), | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" | ||
}; | ||
} |
Oops, something went wrong.