[video] archive videos
This commit is contained in:
parent
215c334fa3
commit
8ca1864351
|
|
@ -46,4 +46,5 @@ app.*.map.json
|
|||
/android/app/profile
|
||||
/android/app/release
|
||||
|
||||
samples/
|
||||
samples/
|
||||
apps_logs.txt
|
||||
|
|
@ -20,6 +20,7 @@ class _SubmitButtonState extends State<SubmitButton> {
|
|||
|
||||
void addVideosListener(BuildContext context, DlFormState state) {
|
||||
if (state.isParsed) {
|
||||
context.read<VideosCubit>().setGlobalStatus('loaded');
|
||||
for (Video video in state.videos) {
|
||||
debugPrint('Adding video: $video');
|
||||
context.read<VideosCubit>().addVideo(video);
|
||||
|
|
@ -45,6 +46,7 @@ class _SubmitButtonState extends State<SubmitButton> {
|
|||
},
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
context.read<VideosCubit>().setGlobalStatus('loading');
|
||||
context.read<DlFormCubit>().parseUrl();
|
||||
},
|
||||
child: Container(
|
||||
|
|
|
|||
|
|
@ -47,10 +47,41 @@ class Home extends StatelessWidget {
|
|||
child: BlocConsumer<VideosCubit, VideosState>(
|
||||
listener: (context, state) {},
|
||||
builder: (context, state) {
|
||||
return ListView.builder(
|
||||
itemCount: state.videoList.length,
|
||||
var returnWidget = <Widget>[];
|
||||
switch (state.status) {
|
||||
case 'loading':
|
||||
returnWidget.add(Center(
|
||||
child: CircularProgressIndicator()));
|
||||
case 'error':
|
||||
returnWidget.add(Center(
|
||||
child: Text('home_dl_error').tr(),
|
||||
));
|
||||
default:
|
||||
returnWidget.add(ListView.builder(
|
||||
itemCount: state.videoList.length,
|
||||
itemBuilder: (context, index) {
|
||||
var currentVideo =
|
||||
state.videoList[index];
|
||||
return ListTile(
|
||||
leading: SizedBox(
|
||||
width: 72,
|
||||
height: 48,
|
||||
child: Image.network(
|
||||
currentVideo.thumbnail,
|
||||
fit: BoxFit.cover),
|
||||
),
|
||||
title: Text(currentVideo.title),
|
||||
subtitle: Text(
|
||||
'${currentVideo.status} - ${currentVideo.format.format}'),
|
||||
);
|
||||
},
|
||||
));
|
||||
}
|
||||
returnWidget.add(ListView.builder(
|
||||
itemCount: state.archiveList.length,
|
||||
itemBuilder: (context, index) {
|
||||
var currentVideo = state.videoList[index];
|
||||
var currentVideo =
|
||||
state.archiveList[index];
|
||||
return ListTile(
|
||||
leading: SizedBox(
|
||||
width: 72,
|
||||
|
|
@ -64,6 +95,9 @@ class Home extends StatelessWidget {
|
|||
'${currentVideo.status} - ${currentVideo.format.format}'),
|
||||
);
|
||||
},
|
||||
));
|
||||
return Stack(
|
||||
children: returnWidget,
|
||||
);
|
||||
})),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -7,5 +7,6 @@
|
|||
"download_folder": "Download folder",
|
||||
"en_US": "English",
|
||||
"fr_FR": "French",
|
||||
"Ok": "OK"
|
||||
"Ok": "OK",
|
||||
"home_dl_error": "Error while downloading the video"
|
||||
}
|
||||
|
|
@ -7,5 +7,6 @@
|
|||
"download_folder": "Dossier de téléchargement",
|
||||
"en_US": "Anglais",
|
||||
"fr_FR": "Français",
|
||||
"Ok": "OK"
|
||||
"Ok": "OK",
|
||||
"home_dl_error": "Erreur lors du téléchargement de la vidéo"
|
||||
}
|
||||
|
|
@ -19,41 +19,54 @@ class VideosCubit extends Cubit<VideosState> {
|
|||
late DLServices dlService;
|
||||
late ConverterService converterService;
|
||||
|
||||
final List<Video> _videoList = [];
|
||||
List<Video> get videoList => _videoList;
|
||||
Iterable<Video> downloadingVid = [];
|
||||
|
||||
int runningTasks = 0;
|
||||
int maxConcurrentTasks = 3;
|
||||
|
||||
void addVideo(Video video) {
|
||||
_videoList.add(video);
|
||||
emit(VideosState(videoList: _videoList));
|
||||
var nVideoList = state.videoList.toList();
|
||||
nVideoList.add(video);
|
||||
emit(VideosState(videoList: nVideoList));
|
||||
}
|
||||
|
||||
void changeStatus(Video video, String status) {
|
||||
int index = _videoList.indexWhere((v) => v.id == video.id);
|
||||
Future<void> changeStatus(Video video, String status) async {
|
||||
var completer = Completer<void>();
|
||||
var tmpVideoList = state.videoList.toList();
|
||||
int index = tmpVideoList.indexWhere((v) => v.id == video.id);
|
||||
|
||||
if (index != -1) {
|
||||
_videoList[index] = video.copyWith(status: status);
|
||||
emit(VideosState(videoList: _videoList));
|
||||
tmpVideoList[index] = video.copyWith(status: status);
|
||||
emit(VideosState(videoList: tmpVideoList));
|
||||
completer.complete();
|
||||
} else {
|
||||
debugPrint('Video not found in the list');
|
||||
completer.completeError('Video not found in the list');
|
||||
}
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
void setGlobalStatus(String status) {
|
||||
emit(VideosState(status: status));
|
||||
}
|
||||
|
||||
void clearVideos() {
|
||||
_videoList.clear();
|
||||
emit(VideosState(videoList: _videoList));
|
||||
emit(VideosState(videoList: []));
|
||||
}
|
||||
|
||||
void removeVideo(Video video) {
|
||||
_videoList.remove(video);
|
||||
emit(VideosState(videoList: _videoList));
|
||||
var nVideoList = state.videoList.where((v) => v.id != video.id).toList();
|
||||
emit(VideosState(videoList: nVideoList));
|
||||
}
|
||||
|
||||
void archiveVideo(Video video) {
|
||||
debugPrint('Archiving video: ${video.title} ${video.format.format}');
|
||||
var nVideoList = state.videoList.where((v) => v.id != video.id).toList();
|
||||
emit(VideosState(videoList: nVideoList, archiveList: [video]));
|
||||
}
|
||||
|
||||
Future<void> startConverter() async {
|
||||
var videosToConvert = _videoList.where((video) =>
|
||||
var videosToConvert = state.videoList.where((video) =>
|
||||
video.status == 'downloaded' &&
|
||||
convertedFormats.contains(video.format));
|
||||
for (Video video in videosToConvert) {
|
||||
|
|
@ -64,20 +77,37 @@ class VideosCubit extends Cubit<VideosState> {
|
|||
|
||||
Future<void> startDownloader() async {
|
||||
dlService = await DLServices.init();
|
||||
downloadingVid =
|
||||
_videoList.where((video) => video.status == 'pending').take(3);
|
||||
|
||||
debugPrint('Videos to download: ${downloadingVid.length}');
|
||||
downloadingVid =
|
||||
state.videoList.where((video) => video.status == 'pending').take(3);
|
||||
|
||||
while (downloadingVid.isNotEmpty && runningTasks < maxConcurrentTasks) {
|
||||
debugPrint('Videos to download: ${downloadingVid.length}');
|
||||
runningTasks++;
|
||||
debugPrint('Concurrent workers: $runningTasks');
|
||||
|
||||
await downloadVideo(downloadingVid.first);
|
||||
downloadingVid =
|
||||
_videoList.where((video) => video.status != 'downloaded');
|
||||
state.videoList.where((video) => video.status == 'pending').take(3);
|
||||
}
|
||||
|
||||
await startConverter();
|
||||
|
||||
await moveVideos();
|
||||
|
||||
final Directory directory = Directory('temp');
|
||||
final List<FileSystemEntity> files = directory.listSync();
|
||||
for (FileSystemEntity file in files) {
|
||||
final String dirFilename = p.basenameWithoutExtension(file.path);
|
||||
if (dirFilename.contains('_tmp')) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
debugPrint('All videos downloaded');
|
||||
}
|
||||
|
||||
Future moveVideos() async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
Directory defaultDownloadDirectory = await getDownloadDirectory();
|
||||
prefs.get('downloadFolder') ??
|
||||
|
|
@ -86,7 +116,8 @@ class VideosCubit extends Cubit<VideosState> {
|
|||
final downloadDirectory = Directory(
|
||||
prefs.getString('downloadFolder') ?? defaultDownloadDirectory.path);
|
||||
|
||||
for (Video video in _videoList) {
|
||||
for (Video video in state.videoList.where((video) =>
|
||||
video.status == 'downloaded' || video.status == 'converted')) {
|
||||
var cleanTitle = video.title.replaceAll(RegExp(r'[^\w\s]+'), '');
|
||||
final tmpFile =
|
||||
File('temp/${video.filename}_done.${video.format.extension}');
|
||||
|
|
@ -97,7 +128,7 @@ class VideosCubit extends Cubit<VideosState> {
|
|||
.catchError((e) => debugPrint('Error creating directory: $e'));
|
||||
debugPrint('Playlist title: $playlistTitle');
|
||||
if (playlistTitle.isNotEmpty && playlistTitle != '') {
|
||||
cleanTitle = playlistTitle + '/' + cleanTitle;
|
||||
cleanTitle = '$playlistTitle/$cleanTitle';
|
||||
}
|
||||
|
||||
final newFile = File(
|
||||
|
|
@ -113,33 +144,10 @@ class VideosCubit extends Cubit<VideosState> {
|
|||
await Future.delayed(Duration(seconds: 1));
|
||||
}
|
||||
}
|
||||
changeStatus(video, 'done');
|
||||
await changeStatus(video, 'done');
|
||||
archiveVideo(video.copyWith(status: 'done'));
|
||||
debugPrint('File moved to ${newFile.path}');
|
||||
}
|
||||
|
||||
final Directory directory = Directory('temp');
|
||||
final List<FileSystemEntity> files = directory.listSync();
|
||||
for (FileSystemEntity file in files) {
|
||||
final String dirFilename = p.basenameWithoutExtension(file.path);
|
||||
if (dirFilename.contains('_tmp')) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
debugPrint('All videos downloaded');
|
||||
/*
|
||||
for (Video video in videosLeft) {
|
||||
final shellStream = await dlService.downloadFile(video.url, video.format);
|
||||
shellStream.listen((line) {
|
||||
if (line.contains('[download]')) {
|
||||
debugPrint('___Download___');
|
||||
debugPrint('%=${line.split('[download]')[1].split(' of')[0].trim()}');
|
||||
debugPrint('______');
|
||||
}
|
||||
debugPrint(line);
|
||||
});
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
Future convertVideo(Video video) async {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
part of 'videos_cubit.dart';
|
||||
|
||||
final class VideosState {
|
||||
final String status;
|
||||
final List<Video> videoList;
|
||||
final List<Video> archiveList;
|
||||
|
||||
VideosState({this.videoList = const []});
|
||||
VideosState(
|
||||
{this.status = 'initial',
|
||||
this.videoList = const [],
|
||||
this.archiveList = const []});
|
||||
|
||||
List<Object> get props => [videoList];
|
||||
List<Object> get props => [videoList, status, archiveList];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -334,7 +334,7 @@ packages:
|
|||
source: hosted
|
||||
version: "2.1.1"
|
||||
logger:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: logger
|
||||
sha256: af05cc8714f356fd1f3888fb6741cbe9fbe25cdb6eedbab80e1a6db21047d4a4
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ dependencies:
|
|||
filesystem_picker: ^4.1.0
|
||||
file_picker: ^8.0.6
|
||||
rename: ^3.0.2
|
||||
logger: ^2.3.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
|
|
|||
Loading…
Reference in New Issue