Create Project Fluttter
Edit main.dart clean code not needed
main.dart
import 'package:flutter/material.dart';
import 'package:youtube_downloader/main_screen.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MainScreen(),
);
}
}
Add plugin in pubspec.yaml
http: ^0.13.4
google_fonts: ^3.0.1
path_provider: ^2.0.11
permission_handler:
dio: ^4.0.6
open_file: ^3.2.1
Create file result.dart & create Class Result
result.dart
import 'dart:convert';
import 'package:http/http.dart' as http;
class Result {
late String? title;
late String? thumb;
late String? filesize_audio;
late String? filesize_video;
late String? audio;
late String? audio_asli;
late String? video;
late String? video_asli;
Result({this.title, this.thumb, this.filesize_audio, this.filesize_video,
this.audio, this.audio_asli, this.video, this.video_asli});
factory Result.createPostResult(Map object){
return Result(
title: object['title'],
thumb: object['thumb'],
filesize_audio: object['filesize_audio'],
filesize_video: object['filesize_video'],
audio: object['audio'],
audio_asli: object['audio_asli'],
video: object['video'],
video_asli: object['video_asli'],
);
}
static Future connectToApi(String url) async{
String apiUrl = 'https://api.akuari.my.id/downloader/youtube?link=' + url;
final response = await http.get(Uri.parse(apiUrl));
if(response.statusCode == 200) {
return Result.createPostResult(jsonDecode(response.body));
} else {
throw Exception('Failed to load url');
}
}
}
Create file main_screen.dart
Create Class MainScreen extends StatefulWidget
main_screen.dart
import 'dart:io';
import 'dart:isolate';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:youtube_downloader/result.dart';
class MainScreen extends StatefulWidget {
const MainScreen({Key? key}) : super(key: key);
@override
State createState() => _MainScreenState();
}
class _MainScreenState extends State {
late Result result;
String url = "";
String title = "";
String thumb = "";
String filesize_audio = "";
String filesize_video = "";
String audio = "";
String audio_asli = "";
String video = "";
String video_asli = "";
String progress = "";
bool isLoading = false;
String directory = "";
final textController = TextEditingController();
final padding = const EdgeInsets.all(8.0);
var dio = Dio();
Future getDownloadPath() async {
Directory? directory;
try {
if (Platform.isIOS) {
directory = await getApplicationDocumentsDirectory();
} else {
directory = Directory('/storage/emulated/0/Download');
// Put file in global download folder, if for an unknown reason it didn't exist, we fallback
// ignore: avoid_slow_async_io
if (!await directory.exists()) directory = await getExternalStorageDirectory();
}
} catch (err) {
print("Cannot get download folder path");
}
return directory!.path;
}
Future downloadVideo(String url, String name, String format) async {
getDownloadPath().then((value){
setState(() {
isLoading = true;
directory = value!;
});
});
// final baseStorage = await getExternalStorageDirectory();
await dio.download(url, directory + "/" + name + format, onReceiveProgress: (rec, total) {
setState(() {
isLoading = false;
progress = "Downloading.. " + ((rec / total) * 100).toStringAsFixed(0) + "%";
});
});
setState(() {
if(progress.contains('100')){
progress = "Download Successful";
}
});
}
@override
Widget build(BuildContext context) {
final padding = EdgeInsets.all(8.0);
return Scaffold(
appBar: AppBar(
title: Text("Youtube Downloader"),
),
body: Center(
child: Padding(
padding: padding,
child: Column(
children: [
Padding(
padding: padding,
child: Column(
children: [
Image.network(
thumb != "" ? thumb : "https://i.ibb.co/qYTFsDx/placeholder.png",
height: 150,
width: 150,),
Text(title),
SizedBox(height: 20,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
downloadVideo(audio, title, ".mp3");
},
child: Row(
children: [
Text("MP3", style: TextStyle(fontSize: 16),),
SizedBox(width: 10,),
Text(filesize_audio, style: TextStyle(fontSize: 12),)
],
),
),
SizedBox(width: 20,),
ElevatedButton(
onPressed: (){
downloadVideo(video, title, ".mp4");
},
child: Row(
children: [
Text("MP4", style: TextStyle(fontSize: 16),),
SizedBox(width: 10,),
Text(filesize_video, style: TextStyle(fontSize: 12),)
],
),
)
],
)
],
),
),
Padding(
padding: padding,
child: TextField(
controller: textController,
decoration: InputDecoration(
contentPadding: EdgeInsets.all(8.0),
hintText: "Paste link youtubenya disini cantik",
suffixIcon: IconButton(
icon: Icon(Icons.search),
onPressed: () async {
setState(() {
url = textController.text;
isLoading = true;
});
await Result.connectToApi(url).then((value){
result = value;
setState(() {
title = result.title!;
thumb = result.thumb!;
filesize_audio = result.filesize_audio!;
filesize_video = result.filesize_video!;
audio = result.audio!;
audio_asli = result.audio_asli!;
video = result.video!;
video_asli = result.video_asli!;
isLoading = false;
});
});
},
)
),
onSubmitted: (url) => Result.connectToApi(url).then((value){
setState(() {
title = result.title!;
thumb = result.thumb!;
filesize_audio = result.filesize_audio!;
filesize_video = result.filesize_video!;
audio = result.audio!;
audio_asli = result.audio_asli!;
video = result.video!;
video_asli = result.video_asli!;
});
}),
),
),
SizedBox(height: 20,),
isLoading ? Center(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: CircularProgressIndicator(),
),
) : Text(progress),
],
),
),
),
);
}
}