You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
140 lines
4.1 KiB
140 lines
4.1 KiB
import 'dart:async';
|
|
import 'dart:convert';
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:get/get.dart';
|
|
import 'package:fluttericon/entypo_icons.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:better_player/better_player.dart';
|
|
|
|
class Video {
|
|
final String uuid;
|
|
final String name;
|
|
final String desc;
|
|
final String speaker;
|
|
final String lang;
|
|
final int duration;
|
|
final String streamURL;
|
|
final String downloadURL;
|
|
|
|
Video(
|
|
{required this.uuid,
|
|
required this.name,
|
|
required this.desc,
|
|
required this.speaker,
|
|
required this.lang,
|
|
required this.duration,
|
|
required this.streamURL,
|
|
required this.downloadURL});
|
|
|
|
factory Video.fromJson(Map<String, dynamic> json) {
|
|
return Video(
|
|
uuid: json['uuid'],
|
|
name: json['name'].split(' | ')[0].split(' by ')[0],
|
|
desc: json['description'],
|
|
speaker: json['name'].split(' | ')[0].split(' by ')[1],
|
|
lang: json['language']['id'],
|
|
duration: json['duration'],
|
|
streamURL: json['files'][0]['fileUrl'],
|
|
downloadURL: json['files'][0]['fileDownloadUrl'],
|
|
);
|
|
}
|
|
}
|
|
|
|
class VideoView extends StatelessWidget {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return FutureBuilder<Video>(
|
|
future: _fetchVideoDetails(),
|
|
builder: (context, snapshot) {
|
|
if (snapshot.hasData) {
|
|
Video? data = snapshot.data;
|
|
return new Scaffold(
|
|
appBar: AppBar(
|
|
title: Text("Video"),
|
|
),
|
|
body: new SingleChildScrollView(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[_videoView(data)],
|
|
),
|
|
));
|
|
} else if (snapshot.hasError) {
|
|
return Text("${snapshot.error}");
|
|
}
|
|
return Container(child: Row(children: [CircularProgressIndicator()]));
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<Video> _fetchVideoDetails() async {
|
|
String uuid = Get.parameters['uuid'] as String;
|
|
final String videoDetailAPI =
|
|
'https://video.ozgurkon.org/api/v1/videos/' + uuid;
|
|
final response = await http.get(Uri.parse(videoDetailAPI));
|
|
|
|
if (response.statusCode == 200) {
|
|
var jsonResponse = json.decode(response.body);
|
|
final description =
|
|
await http.get(Uri.parse(videoDetailAPI + '/description'));
|
|
if (description.statusCode == 200) {
|
|
var descriptionResponse = json.decode(description.body);
|
|
jsonResponse['description'] = descriptionResponse['description'];
|
|
}
|
|
return Video.fromJson(jsonResponse);
|
|
} else {
|
|
throw Exception('Failed to load video details from API');
|
|
}
|
|
}
|
|
|
|
Card _videoView(data) {
|
|
return Card(
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
AspectRatio(
|
|
aspectRatio: 16 / 9,
|
|
child: BetterPlayer.network(
|
|
data!.streamURL,
|
|
betterPlayerConfiguration: BetterPlayerConfiguration(
|
|
aspectRatio: 16 / 9,
|
|
autoPlay: true,
|
|
),
|
|
),
|
|
),
|
|
ListTile(
|
|
title: Text(data.name),
|
|
subtitle: Text(data.speaker),
|
|
trailing: Row(mainAxisSize: MainAxisSize.min, children: <Widget>[
|
|
Icon(Entypo.cc),
|
|
Icon(Entypo.cc_by),
|
|
Icon(Entypo.cc_sa)
|
|
]),
|
|
),
|
|
Padding(
|
|
padding: const EdgeInsets.all(16.0),
|
|
child: Text(
|
|
data.desc,
|
|
style: TextStyle(color: Colors.black.withOpacity(0.6)),
|
|
),
|
|
),
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
children: <Widget>[
|
|
TextButton(
|
|
child: const Text('DOWNLOAD'),
|
|
onPressed: () {
|
|
Get.toNamed('/videoplayer', arguments: data.streamURL);
|
|
},
|
|
),
|
|
const SizedBox(width: 8),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|