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.
 
 
 
 
 
 
ozgurkon-app/lib/screens/VideoPlayer.dart

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