Skip to content

Commit

Permalink
FFmpeg: First implementation to convert downloaded Songs
Browse files Browse the repository at this point in the history
  • Loading branch information
Artx-II committed Apr 15, 2020
1 parent 0e7e1fc commit d72fc56
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 3 deletions.
2 changes: 1 addition & 1 deletion android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ android {
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.songtube"
minSdkVersion 16
minSdkVersion 24
targetSdkVersion 28
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
Expand Down
14 changes: 14 additions & 0 deletions android/app/src/main/java/com/example/songtube/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import android.content.Context;
import android.net.Uri;
import java.io.File;

public class MainActivity extends FlutterActivity {
String sharedText;
private static final String CHANNEL = "sharedTextChannel";
private static final String CONVERTERCHANNEL = "registerMedia";
@Override
public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine);
Expand All @@ -23,6 +27,16 @@ public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
}
}
);
new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CONVERTERCHANNEL)
.setMethodCallHandler(
(call, result) -> {
if (call.method.equals("registerFile")) {
String argument = call.argument("file");
File file = new File(argument);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
}
}
);
}

@Override
Expand Down
5 changes: 5 additions & 0 deletions lib/internal/native.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ NativeMethod method;

class NativeMethod {

static const media = const MethodChannel("registerMedia");
static const platform = const MethodChannel("sharedTextChannel");
String _sharedIntent;

Expand All @@ -22,4 +23,8 @@ class NativeMethod {
}
}

void registerFile(String file) async {
await media.invokeMethod('registerFile', {"file":file});
}

}
87 changes: 86 additions & 1 deletion lib/internal/songtube_classes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,89 @@ import 'dart:async';
import 'dart:io';
import 'package:ext_storage/ext_storage.dart';
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';
import 'native.dart';
import 'package:image_downloader/image_downloader.dart';

Downloader downloader;
AppStreams appdata;
Converter converter;

enum FFmpegArgs { argsToACC }

class Converter {

// Declare our FFmpeg instances
final FlutterFFmpeg flutterFFmpeg = new FlutterFFmpeg();
final FlutterFFprobe flutterFFprobe = new FlutterFFprobe();

// Get the data we need before declaring our Argument lists
Future<List<String>> getArgumentsList(FFmpegArgs type, MediaMetaData metadata, [String path]) async {

List<String> _argsList;
String _path;
String _finalPath;

if (path != null) _path = path;
if (path == null) _path = await ExternalPath().externalMusic;
_finalPath = _path + "/" + metadata.title;
if (type == FFmpegArgs.argsToACC) {
_argsList = [
"-i",
appdata.getLastFilePath,
"-c:a", "aac",
"-profile:a", "aac_low",
"-metadata", "title=${metadata.title}",
"-metadata", "album=${metadata.album}",
"-metadata", "artist=${metadata.artist}",
"-metadata", "genre=${metadata.genre}",
"-metadata", "date=${metadata.date}",
"-metadata", "disk=${metadata.disk}",
"-metadata", "track=${metadata.track}",
"$_finalPath.m4a",
];
}
print("Full path: " + _argsList.last);
return _argsList;

}

// Functions to convert media
Future<int> convertAudio(List<String> arguments) async {
print("Converter: Starting audio file convertion...");
int _result;
await flutterFFmpeg.executeWithArguments(arguments).then(
(value) {
File(appdata.getLastFilePath).delete();
method.registerFile(arguments.last);
_result = value;
}
);
print("Converter: Done, result: " + _result.toString());
return _result;
}

}

class MediaMetaData {

String title;
String album;
String artist;
String genre;
String coverurl;
String date;
String disk;
String track;

MediaMetaData(this.title, this.album, this.artist, this.genre,
this.coverurl, this.date, this.disk, this.track);

}

class Downloader {
String id;
MediaMetaData defaultMetaData;

Downloader() {
appdata.isDownloading.add(false);
Expand All @@ -28,6 +105,10 @@ class Downloader {
appdata.audioDuration.add(mediaStream.videoDetails.duration);
appdata.audioSize.add(audio.size);
appdata.linkReady.add(true);
defaultMetaData = MediaMetaData(mediaStream.videoDetails.title, mediaStream.videoDetails.author,
mediaStream.videoDetails.author, "Any", mediaStream.videoDetails.thumbnailSet.maxResUrl,
mediaStream.videoDetails.uploadDate.toString(),
"Any", "Any");
id = _id;
yt.close();
return 1;
Expand All @@ -44,7 +125,7 @@ class Downloader {
var audio = mediaStream.audio.last;

// Compose the file name removing the unallowed characters in windows.
var fileName = '${mediaStream.videoDetails.title}.m4a'
var fileName = '${mediaStream.videoDetails.title}'
.replaceAll('Container.', '')
.replaceAll(r'\', '')
.replaceAll('/', '')
Expand Down Expand Up @@ -79,6 +160,8 @@ class Downloader {
}
await output.close();
appdata.getLastFilePath = "$directory/$fileName";
appdata.getFileName = "$fileName";
appdata.getDownloadPath = directory;
appdata.isDownloading.add(false);
print("Downloader: All done");
}
Expand Down Expand Up @@ -109,7 +192,9 @@ class AppStreams {
StreamController<String> audioTitle = new StreamController.broadcast();
StreamController<String> audioArtist = new StreamController.broadcast();

String getFileName;
String getLastFilePath;
String getDownloadPath;

void unloadStreams() {
audioSize.add(null);
Expand Down
7 changes: 7 additions & 0 deletions lib/library.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_downloader/image_downloader.dart';
import 'tabs/downloadtab.dart';
import 'tabs/hometab.dart';
import 'tabs/settingstab.dart';
Expand All @@ -20,6 +21,7 @@ class _LibraryState extends State<Library> {
appdata = AppStreams();
downloader = Downloader();
method = NativeMethod();
converter = Converter();
super.initState();
}

Expand Down Expand Up @@ -110,6 +112,11 @@ class _LibraryState extends State<Library> {
child: FloatingActionButton(
onPressed: () async {
await downloader.download();
List<String> list = await converter.getArgumentsList(FFmpegArgs.argsToACC,
downloader.defaultMetaData);
int result = await converter.convertAudio(list);
if (result == 0) print("Library: Audio convertion done successful");
if (result == 1) print("Library: Audio convertion failed");
},
child: Icon(
Icons.file_download,
Expand Down
2 changes: 1 addition & 1 deletion lib/tabs/hometab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class HomeTab extends StatefulWidget {
}

class _HomeTabState extends State<HomeTab> with AutomaticKeepAliveClientMixin<HomeTab>, WidgetsBindingObserver {

@override
void didChangeAppLifecycleState(AppLifecycleState state) async {
switch (state){
Expand Down

0 comments on commit d72fc56

Please sign in to comment.