From f5783c2a25b8c0700ac5ce71a8267c562e26d81d Mon Sep 17 00:00:00 2001 From: "Oklamcak, Tomas" Date: Tue, 3 Nov 2020 23:48:21 +0100 Subject: [PATCH 1/4] mp3 and amr extension --- app/build.gradle | 10 ++ app/lib/.gitignore | 1 + app/lib/build.gradle | 24 ++++ app/lib/proguard-rules.pro | 17 +++ app/lib/src/main/AndroidManifest.xml | 7 + .../AndroidAudioConverter.java | 135 ++++++++++++++++++ .../callback/IConvertCallback.java | 11 ++ .../callback/ILoadCallback.java | 9 ++ .../model/AudioFormat.java | 14 ++ app/lib/src/main/res/values/strings.xml | 3 + .../activities/MainActivity.java | 16 +++ .../adapters/FileViewerAdapter.java | 9 +- .../fragments/RecordFragment.java | 39 +++++ .../fragments/SettingsFragment.java | 28 +++- .../services/RecordingService.java | 96 +++++++++++-- .../main/res/layout/dialog_rename_file.xml | 8 -- app/src/main/res/values/array.xml | 28 ++++ app/src/main/res/values/strings.xml | 9 ++ app/src/main/res/xml/preferences.xml | 11 ++ 19 files changed, 457 insertions(+), 18 deletions(-) create mode 100644 app/lib/.gitignore create mode 100644 app/lib/build.gradle create mode 100644 app/lib/proguard-rules.pro create mode 100644 app/lib/src/main/AndroidManifest.xml create mode 100644 app/lib/src/main/java/cafe/adriel/androidaudioconverter/AndroidAudioConverter.java create mode 100644 app/lib/src/main/java/cafe/adriel/androidaudioconverter/callback/IConvertCallback.java create mode 100644 app/lib/src/main/java/cafe/adriel/androidaudioconverter/callback/ILoadCallback.java create mode 100644 app/lib/src/main/java/cafe/adriel/androidaudioconverter/model/AudioFormat.java create mode 100644 app/lib/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/array.xml diff --git a/app/build.gradle b/app/build.gradle index a8742302..6dcd605f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,6 +6,13 @@ android { compileSdkVersion 29 buildToolsVersion '29.0.2' + + repositories { + maven { + url "https://jitpack.io" + } + } + defaultConfig { applicationId 'by.naxa.soundrecorder' minSdkVersion 16 @@ -37,6 +44,7 @@ dependencies { implementation 'com.google.android.material:material:1.1.+' implementation 'com.googlecode.mp4parser:isoparser:1.1.22' implementation 'com.budiyev.android:circular-progress-bar:1.2.0' + implementation files('C:\\Users\\toklamca\\Desktop\\CUDA\\jave-1.0.2.jar') // detect memory leaks debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1' @@ -54,4 +62,6 @@ dependencies { // Firebase implementation 'com.google.firebase:firebase-analytics:17.2.1' implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' + compile 'com.github.adrielcafe:AndroidAudioConverter:0.0.8' + } diff --git a/app/lib/.gitignore b/app/lib/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/app/lib/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/lib/build.gradle b/app/lib/build.gradle new file mode 100644 index 00000000..47d4389d --- /dev/null +++ b/app/lib/build.gradle @@ -0,0 +1,24 @@ +apply plugin: 'com.android.library' + +android { + compileSdkVersion 24 + buildToolsVersion "24.0.1" + + defaultConfig { + minSdkVersion 16 + targetSdkVersion 24 + versionCode 1 + versionName "1.0" + + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile 'com.github.adrielcafe:ffmpeg-android-java:2a627f6ecd@aar' +} \ No newline at end of file diff --git a/app/lib/proguard-rules.pro b/app/lib/proguard-rules.pro new file mode 100644 index 00000000..f83ae791 --- /dev/null +++ b/app/lib/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/adrielcafe/Android/sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/app/lib/src/main/AndroidManifest.xml b/app/lib/src/main/AndroidManifest.xml new file mode 100644 index 00000000..481879ec --- /dev/null +++ b/app/lib/src/main/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/app/lib/src/main/java/cafe/adriel/androidaudioconverter/AndroidAudioConverter.java b/app/lib/src/main/java/cafe/adriel/androidaudioconverter/AndroidAudioConverter.java new file mode 100644 index 00000000..95bf2268 --- /dev/null +++ b/app/lib/src/main/java/cafe/adriel/androidaudioconverter/AndroidAudioConverter.java @@ -0,0 +1,135 @@ +package cafe.adriel.androidaudioconverter; + +import android.content.Context; + +import com.github.hiteshsondhi88.libffmpeg.FFmpeg; +import com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteResponseHandler; +import com.github.hiteshsondhi88.libffmpeg.FFmpegLoadBinaryResponseHandler; + +import java.io.File; +import java.io.IOException; + +import cafe.adriel.androidaudioconverter.callback.IConvertCallback; +import cafe.adriel.androidaudioconverter.callback.ILoadCallback; +import cafe.adriel.androidaudioconverter.model.AudioFormat; + +public class AndroidAudioConverter { + + private static boolean loaded; + + private Context context; + private File audioFile; + private AudioFormat format; + private IConvertCallback callback; + + private AndroidAudioConverter(Context context){ + this.context = context; + } + + public static boolean isLoaded(){ + return loaded; + } + + public static void load(Context context, final ILoadCallback callback){ + try { + FFmpeg.getInstance(context).loadBinary(new FFmpegLoadBinaryResponseHandler() { + @Override + public void onStart() { + + } + + @Override + public void onSuccess() { + loaded = true; + callback.onSuccess(); + } + + @Override + public void onFailure() { + loaded = false; + callback.onFailure(new Exception("Failed to loaded FFmpeg lib")); + } + + @Override + public void onFinish() { + + } + }); + } catch (Exception e){ + loaded = false; + callback.onFailure(e); + } + } + + public static AndroidAudioConverter with(Context context) { + return new AndroidAudioConverter(context); + } + + public AndroidAudioConverter setFile(File originalFile) { + this.audioFile = originalFile; + return this; + } + + public AndroidAudioConverter setFormat(AudioFormat format) { + this.format = format; + return this; + } + + public AndroidAudioConverter setCallback(IConvertCallback callback) { + this.callback = callback; + return this; + } + + public void convert() { + if(!isLoaded()){ + callback.onFailure(new Exception("FFmpeg not loaded")); + return; + } + if(audioFile == null || !audioFile.exists()){ + callback.onFailure(new IOException("File not exists")); + return; + } + if(!audioFile.canRead()){ + callback.onFailure(new IOException("Can't read the file. Missing permission?")); + return; + } + final File convertedFile = getConvertedFile(audioFile, format); + final String[] cmd = new String[]{"-y", "-i", audioFile.getPath(), convertedFile.getPath()}; + try { + FFmpeg.getInstance(context).execute(cmd, new FFmpegExecuteResponseHandler() { + @Override + public void onStart() { + + } + + @Override + public void onProgress(String message) { + + } + + @Override + public void onSuccess(String message) { + callback.onSuccess(convertedFile); + } + + @Override + public void onFailure(String message) { + callback.onFailure(new IOException(message)); + } + + @Override + public void onFinish() { + + } + }); + } catch (Exception e){ + callback.onFailure(e); + } + } + + private static File getConvertedFile(File originalFile, AudioFormat format){ + String[] f = originalFile.getPath().split("\\."); + String filePath = originalFile.getPath().replace(f[f.length - 1], format.getFormat()); + return new File(filePath); + } +} \ No newline at end of file diff --git a/app/lib/src/main/java/cafe/adriel/androidaudioconverter/callback/IConvertCallback.java b/app/lib/src/main/java/cafe/adriel/androidaudioconverter/callback/IConvertCallback.java new file mode 100644 index 00000000..e007f320 --- /dev/null +++ b/app/lib/src/main/java/cafe/adriel/androidaudioconverter/callback/IConvertCallback.java @@ -0,0 +1,11 @@ +package cafe.adriel.androidaudioconverter.callback; + +import java.io.File; + +public interface IConvertCallback { + + void onSuccess(File convertedFile); + + void onFailure(Exception error); + +} \ No newline at end of file diff --git a/app/lib/src/main/java/cafe/adriel/androidaudioconverter/callback/ILoadCallback.java b/app/lib/src/main/java/cafe/adriel/androidaudioconverter/callback/ILoadCallback.java new file mode 100644 index 00000000..ccb4ad77 --- /dev/null +++ b/app/lib/src/main/java/cafe/adriel/androidaudioconverter/callback/ILoadCallback.java @@ -0,0 +1,9 @@ +package cafe.adriel.androidaudioconverter.callback; + +public interface ILoadCallback { + + void onSuccess(); + + void onFailure(Exception error); + +} \ No newline at end of file diff --git a/app/lib/src/main/java/cafe/adriel/androidaudioconverter/model/AudioFormat.java b/app/lib/src/main/java/cafe/adriel/androidaudioconverter/model/AudioFormat.java new file mode 100644 index 00000000..4bc2ac86 --- /dev/null +++ b/app/lib/src/main/java/cafe/adriel/androidaudioconverter/model/AudioFormat.java @@ -0,0 +1,14 @@ +package cafe.adriel.androidaudioconverter.model; + +public enum AudioFormat { + AAC, + MP3, + M4A, + WMA, + WAV, + FLAC; + + public String getFormat() { + return name().toLowerCase(); + } +} \ No newline at end of file diff --git a/app/lib/src/main/res/values/strings.xml b/app/lib/src/main/res/values/strings.xml new file mode 100644 index 00000000..da0b9ffa --- /dev/null +++ b/app/lib/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + AndroidAudioConverter + \ No newline at end of file diff --git a/app/src/main/java/by/naxa/soundrecorder/activities/MainActivity.java b/app/src/main/java/by/naxa/soundrecorder/activities/MainActivity.java index 9e9a40d3..d84dd760 100644 --- a/app/src/main/java/by/naxa/soundrecorder/activities/MainActivity.java +++ b/app/src/main/java/by/naxa/soundrecorder/activities/MainActivity.java @@ -34,6 +34,8 @@ import by.naxa.soundrecorder.fragments.FileViewerFragment; import by.naxa.soundrecorder.fragments.RecordFragment; import by.naxa.soundrecorder.util.EventBroadcaster; +import cafe.adriel.androidaudioconverter.AndroidAudioConverter; +import cafe.adriel.androidaudioconverter.callback.ILoadCallback; public class MainActivity extends AppCompatActivity { @@ -45,6 +47,20 @@ public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + + AndroidAudioConverter.load(this, new ILoadCallback() { + @Override + public void onSuccess() { + // Great! + } + @Override + public void onFailure(Exception error) { + // FFmpeg is not supported by device + } + }); + + if (SoundRecorderApplication.getInstance().isNightModeEnabled()) { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); //For night mode theme } else { diff --git a/app/src/main/java/by/naxa/soundrecorder/adapters/FileViewerAdapter.java b/app/src/main/java/by/naxa/soundrecorder/adapters/FileViewerAdapter.java index c5d2e6d4..1469c2fe 100644 --- a/app/src/main/java/by/naxa/soundrecorder/adapters/FileViewerAdapter.java +++ b/app/src/main/java/by/naxa/soundrecorder/adapters/FileViewerAdapter.java @@ -30,11 +30,13 @@ import androidx.fragment.app.FragmentTransaction; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; + import by.naxa.soundrecorder.BuildConfig; import by.naxa.soundrecorder.DBHelper; import by.naxa.soundrecorder.R; import by.naxa.soundrecorder.RecordingItem; import by.naxa.soundrecorder.fragments.PlaybackFragment; +import by.naxa.soundrecorder.fragments.SettingsFragment; import by.naxa.soundrecorder.listeners.OnDatabaseChangedListener; import by.naxa.soundrecorder.listeners.OnSingleClickListener; import by.naxa.soundrecorder.util.EventBroadcaster; @@ -275,12 +277,16 @@ private void shareFileDialog(int position) { } private void renameFileDialog(final int position) { + // File rename dialog AlertDialog.Builder renameFileBuilder = new AlertDialog.Builder(mContext); LayoutInflater inflater = LayoutInflater.from(mContext); View view = inflater.inflate(R.layout.dialog_rename_file, null); + // TextView textView = (TextView) view.findViewById(R.id.textView); + // textView.setText(SettingsFragment.getFormat()); + final TextInputEditText input = view.findViewById(R.id.new_name); renameFileBuilder.setTitle(mContext.getString(R.string.dialog_title_rename)); @@ -292,7 +298,8 @@ public void onClick(DialogInterface dialog, int id) { final Editable editable = input.getText(); if (editable == null) return; - final String value = editable.toString().trim() + ".mp4"; + + final String value = editable.toString().trim() + SettingsFragment.getFormat(); rename(position, value); } catch (Exception e) { if (Fabric.isInitialized()) Crashlytics.logException(e); diff --git a/app/src/main/java/by/naxa/soundrecorder/fragments/RecordFragment.java b/app/src/main/java/by/naxa/soundrecorder/fragments/RecordFragment.java index 1ea3819a..e1599af6 100644 --- a/app/src/main/java/by/naxa/soundrecorder/fragments/RecordFragment.java +++ b/app/src/main/java/by/naxa/soundrecorder/fragments/RecordFragment.java @@ -20,6 +20,7 @@ import android.view.ViewGroup; import android.widget.Chronometer; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -45,6 +46,9 @@ import by.naxa.soundrecorder.util.Paths; import by.naxa.soundrecorder.util.PermissionsHelper; import by.naxa.soundrecorder.util.ScreenLock; +import cafe.adriel.androidaudioconverter.AndroidAudioConverter; +import cafe.adriel.androidaudioconverter.callback.IConvertCallback; +import cafe.adriel.androidaudioconverter.model.AudioFormat; /** * A simple {@link Fragment} subclass. @@ -329,7 +333,42 @@ private void updateUI(RecorderState state, long chronometerBaseTime) { /** * Stop recording */ + + public void convertAudio(){ + /** + * Update with a valid audio file! + * Supported formats: {@link AndroidAudioConverter.AudioFormat} + */ + String path = Paths.combine( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC), + Paths.SOUND_RECORDER_FOLDER, "My Recording_1.mp4"); + + File source = new File(path); + + IConvertCallback callback = new IConvertCallback() { + @Override + public void onSuccess(File convertedFile) { + Toast.makeText(getContext(), "SUCCESS: " + convertedFile.getPath(), Toast.LENGTH_LONG).show(); + } + @Override + public void onFailure(Exception error) { + Toast.makeText(getContext(), "ERROR: " + error.getMessage(), Toast.LENGTH_LONG).show(); + } + }; + + + Toast.makeText(getContext(), "Converting audio file...", Toast.LENGTH_SHORT).show(); + AndroidAudioConverter.with(getContext()) + .setFile(source) + .setFormat(AudioFormat.MP3) + .setCallback(callback) + .convert(); + } + + private void stopRecording() { + + final FragmentActivity activity = getActivity(); if (activity == null) { Log.wtf(LOG_TAG, "RecordFragment failed to stop recording, getActivity() returns null."); diff --git a/app/src/main/java/by/naxa/soundrecorder/fragments/SettingsFragment.java b/app/src/main/java/by/naxa/soundrecorder/fragments/SettingsFragment.java index 993aa170..fc0a28b5 100644 --- a/app/src/main/java/by/naxa/soundrecorder/fragments/SettingsFragment.java +++ b/app/src/main/java/by/naxa/soundrecorder/fragments/SettingsFragment.java @@ -1,10 +1,15 @@ package by.naxa.soundrecorder.fragments; +import android.content.Context; +import android.content.SharedPreferences; import android.os.Bundle; import android.preference.CheckBoxPreference; +import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; import android.preference.SwitchPreference; +import android.widget.CheckBox; import android.widget.Toast; import androidx.annotation.Nullable; @@ -21,14 +26,31 @@ * Created by Daniel on 5/22/2017. */ public class SettingsFragment extends PreferenceFragment { + private static String format = ".mp4"; + @Override public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); + final ListPreference listPreferenceCategory = (ListPreference) findPreference("pref_list"); + + + listPreferenceCategory.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + public boolean onPreferenceChange(Preference preference, Object newValue) { + format = newValue.toString(); + Toast.makeText(getActivity(), "Selected: "+format, Toast.LENGTH_LONG).show(); + + return true; + } + }); + + final CheckBoxPreference highQualityPref = (CheckBoxPreference) findPreference( getResources().getString(R.string.pref_high_quality_key)); + highQualityPref.setChecked(MySharedPreferences.getPrefHighQuality(getActivity())); highQualityPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override @@ -62,7 +84,7 @@ public boolean onPreferenceClick(Preference preference) { darkModePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { - if(darkModePref.isChecked()) { + if (darkModePref.isChecked()) { SoundRecorderApplication.getInstance().setIsNightModeEnabled(false); Toast.makeText(getActivity(), "Dark Mode is OFF", Toast.LENGTH_SHORT).show(); darkModePref.setChecked(false); @@ -77,4 +99,8 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { } }); } + + public static String getFormat() { + return format; + } } diff --git a/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java b/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java index 73447df0..3773174a 100644 --- a/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java +++ b/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java @@ -1,7 +1,11 @@ package by.naxa.soundrecorder.services; +import android.app.AlertDialog; import android.app.Service; +import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; +import android.media.AudioRecord; import android.media.MediaRecorder; import android.os.Binder; import android.os.Environment; @@ -28,17 +32,28 @@ import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; +import java.util.Set; import by.naxa.soundrecorder.DBHelper; import by.naxa.soundrecorder.R; import by.naxa.soundrecorder.RecorderState; +import by.naxa.soundrecorder.activities.MainActivity; +import by.naxa.soundrecorder.fragments.RecordFragment; +import by.naxa.soundrecorder.fragments.SettingsFragment; import by.naxa.soundrecorder.util.Command; import by.naxa.soundrecorder.util.EventBroadcaster; import by.naxa.soundrecorder.util.MyIntentBuilder; import by.naxa.soundrecorder.util.MySharedPreferences; import by.naxa.soundrecorder.util.NotificationCompatPie; import by.naxa.soundrecorder.util.Paths; +import cafe.adriel.androidaudioconverter.AndroidAudioConverter; +import cafe.adriel.androidaudioconverter.callback.IConvertCallback; +import cafe.adriel.androidaudioconverter.model.AudioFormat; import io.fabric.sdk.android.Fabric; +import it.sauronsoftware.jave.AudioAttributes; +import it.sauronsoftware.jave.Encoder; +import it.sauronsoftware.jave.EncoderException; +import it.sauronsoftware.jave.EncodingAttributes; /** * Created by Daniel on 12/28/2014. @@ -46,10 +61,12 @@ public class RecordingService extends Service { private static final String LOG_TAG = "RecordingService"; + cafe.adriel.androidaudioconverter.model.AudioFormat a; private String mFileName = null; private String mFilePath = null; + private MediaRecorder mRecorder = null; private DBHelper mDatabase; @@ -57,6 +74,7 @@ public class RecordingService extends Service { private long mStartingTimeMillis = 0; private long mElapsedMillis = 0; + private volatile RecorderState state = RecorderState.STOPPED; private int tempFileCount = 0; @@ -66,6 +84,10 @@ public class RecordingService extends Service { // Binder given to clients private final IBinder mBinder = new LocalBinder(); + public RecordingService() { + + } + @Override public IBinder onBind(Intent intent) { @@ -134,30 +156,38 @@ private void processCommand(@Command int command) { } } - public void stopService() { + public void stopService() throws EncoderException, IOException { Log.d(LOG_TAG, "RecordingService#stopService()"); stopRecording(); stopForeground(true); stopSelf(); } + @Override public void onDestroy() { if (mRecorder != null) { - stopRecording(); + try { + stopRecording(); + } catch (EncoderException | IOException e) { + e.printStackTrace(); + } } super.onDestroy(); } public void setFileNameAndPath(boolean isFilePathTemp) { + if (isFilePathTemp) { - mFileName = getString(R.string.default_file_name) + (++tempFileCount) + "_" + ".tmp"; + mFileName = getString(R.string.default_file_name) + (++tempFileCount) + "_" + SettingsFragment.getFormat(); Paths.createDirectory(getExternalCacheDir(), Paths.SOUND_RECORDER_FOLDER); mFilePath = Paths.combine( getExternalCacheDir(), Paths.SOUND_RECORDER_FOLDER, mFileName); } else { + + int count = 0; File f; @@ -165,7 +195,7 @@ public void setFileNameAndPath(boolean isFilePathTemp) { ++count; mFileName = - getString(R.string.default_file_name) + "_" + (mDatabase.getCount() + count) + ".mp4"; + getString(R.string.default_file_name) + "_" + (mDatabase.getCount() + count) + SettingsFragment.getFormat(); mFilePath = Paths.combine( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC), @@ -180,20 +210,30 @@ public void setFileNameAndPath(boolean isFilePathTemp) { * Start or resume sound recording. */ public void startRecording() { + if (state == RecorderState.RECORDING || state == RecorderState.PREPARING) return; changeStateTo(RecorderState.PREPARING); boolean isTemporary = true; setFileNameAndPath(isTemporary); - // Configure the MediaRecorder for a new recording mRecorder = new MediaRecorder(); mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); - mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + + if(SettingsFragment.getFormat().equals(".amr")){ + + mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); + mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); + } + else { + + mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + } mRecorder.setOutputFile(mFilePath); - mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); mRecorder.setAudioChannels(1); + if (MySharedPreferences.getPrefHighQuality(this)) { mRecorder.setAudioSamplingRate(44100); mRecorder.setAudioEncodingBitRate(192000); @@ -244,7 +284,37 @@ public void pauseRecording() { } } - public void stopRecording() { + public void convertAudio() { + + String saa = Paths.combine( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC), + Paths.SOUND_RECORDER_FOLDER, "My Recording_1.mp4"); + + File source = new File(mFilePath); + + IConvertCallback callback = new IConvertCallback() { + @Override + public void onSuccess(File convertedFile) { + Toast.makeText(getApplicationContext(), "SUCCESS: " + convertedFile.getPath(), Toast.LENGTH_LONG).show(); + } + + @Override + public void onFailure(Exception error) { + Toast.makeText(getApplicationContext(), "ERROR: " + error.getMessage(), Toast.LENGTH_LONG).show(); + } + }; + + Toast.makeText(getApplicationContext(), "Converting...", Toast.LENGTH_SHORT).show(); + AndroidAudioConverter.with(getApplicationContext()) + .setFile(source) + .setFormat(AudioFormat.MP3) + .setCallback(callback) + .convert(); + } + + + public void stopRecording() throws EncoderException, IOException { + if (state == RecorderState.STOPPED) { Log.wtf(LOG_TAG, "stopRecording: already STOPPED."); return; @@ -257,7 +327,10 @@ public void stopRecording() { filesPaused.add(mFilePath); boolean isTemporary = false; + + setFileNameAndPath(isTemporary); + String pathToSend = ""; try { if (stateBefore != RecorderState.PAUSED) { @@ -287,12 +360,19 @@ public void stopRecording() { } } + try { mDatabase.addRecording(mFileName, mFilePath, mElapsedMillis); } catch (Exception e) { if (Fabric.isInitialized()) Crashlytics.logException(e); Log.e(LOG_TAG, "exception", e); } + + + if (SettingsFragment.getFormat().equals(".mp3")) { + convertAudio(); + + } } /** diff --git a/app/src/main/res/layout/dialog_rename_file.xml b/app/src/main/res/layout/dialog_rename_file.xml index af73b96f..dc9753c8 100644 --- a/app/src/main/res/layout/dialog_rename_file.xml +++ b/app/src/main/res/layout/dialog_rename_file.xml @@ -17,12 +17,4 @@ android:focusedByDefault="true" android:maxLines="1" /> - - \ No newline at end of file diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml new file mode 100644 index 00000000..c2aaa8cb --- /dev/null +++ b/app/src/main/res/values/array.xml @@ -0,0 +1,28 @@ + + + + + MP4 + + + MP3 + + + AMR + + + + + + + + .mp4 + + + .mp3 + + + .amr + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0fee3b2d..2e47b55c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -40,6 +40,15 @@ Yes, delete No + + Settings + Android Example - ListPreference + + + userName + foregroundColor + backgroundColor + No saved recordings Pause Resume diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index f1ddd32f..8bb2c6df 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -9,12 +9,23 @@ android:title="@string/pref_high_quality_title" android:summary="@string/pref_high_quality_desc"/> + + + + Date: Tue, 3 Nov 2020 23:52:49 +0100 Subject: [PATCH 2/4] mp3 and amr extension --- app/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 6dcd605f..ca5817e7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -44,7 +44,6 @@ dependencies { implementation 'com.google.android.material:material:1.1.+' implementation 'com.googlecode.mp4parser:isoparser:1.1.22' implementation 'com.budiyev.android:circular-progress-bar:1.2.0' - implementation files('C:\\Users\\toklamca\\Desktop\\CUDA\\jave-1.0.2.jar') // detect memory leaks debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1' From edb24f9d211a6bba3f975f8918f60271b8850bf3 Mon Sep 17 00:00:00 2001 From: Tomas Oklamcak Date: Wed, 4 Nov 2020 01:27:54 +0100 Subject: [PATCH 3/4] clean code --- .../services/RecordingService.java | 29 +++++-------------- 1 file changed, 8 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java b/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java index 3773174a..6da229f3 100644 --- a/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java +++ b/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java @@ -1,11 +1,7 @@ package by.naxa.soundrecorder.services; -import android.app.AlertDialog; import android.app.Service; -import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; -import android.media.AudioRecord; import android.media.MediaRecorder; import android.os.Binder; import android.os.Environment; @@ -32,13 +28,10 @@ import java.util.ArrayList; import java.util.List; import java.util.NoSuchElementException; -import java.util.Set; import by.naxa.soundrecorder.DBHelper; import by.naxa.soundrecorder.R; import by.naxa.soundrecorder.RecorderState; -import by.naxa.soundrecorder.activities.MainActivity; -import by.naxa.soundrecorder.fragments.RecordFragment; import by.naxa.soundrecorder.fragments.SettingsFragment; import by.naxa.soundrecorder.util.Command; import by.naxa.soundrecorder.util.EventBroadcaster; @@ -50,10 +43,6 @@ import cafe.adriel.androidaudioconverter.callback.IConvertCallback; import cafe.adriel.androidaudioconverter.model.AudioFormat; import io.fabric.sdk.android.Fabric; -import it.sauronsoftware.jave.AudioAttributes; -import it.sauronsoftware.jave.Encoder; -import it.sauronsoftware.jave.EncoderException; -import it.sauronsoftware.jave.EncodingAttributes; /** * Created by Daniel on 12/28/2014. @@ -156,7 +145,7 @@ private void processCommand(@Command int command) { } } - public void stopService() throws EncoderException, IOException { + public void stopService() { Log.d(LOG_TAG, "RecordingService#stopService()"); stopRecording(); stopForeground(true); @@ -167,13 +156,12 @@ public void stopService() throws EncoderException, IOException { @Override public void onDestroy() { if (mRecorder != null) { - try { - stopRecording(); - } catch (EncoderException | IOException e) { - e.printStackTrace(); - } + + stopRecording(); + } + super.onDestroy(); } @@ -221,12 +209,11 @@ public void startRecording() { mRecorder = new MediaRecorder(); mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); - if(SettingsFragment.getFormat().equals(".amr")){ + if (SettingsFragment.getFormat().equals(".amr")) { mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); - } - else { + } else { mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); @@ -313,7 +300,7 @@ public void onFailure(Exception error) { } - public void stopRecording() throws EncoderException, IOException { + public void stopRecording() { if (state == RecorderState.STOPPED) { Log.wtf(LOG_TAG, "stopRecording: already STOPPED."); From 49014a0cd404bbb2dca130a5a4457093933abf3a Mon Sep 17 00:00:00 2001 From: Tomas Oklamcak Date: Wed, 4 Nov 2020 01:55:16 +0100 Subject: [PATCH 4/4] rename add format --- .../by/naxa/soundrecorder/adapters/FileViewerAdapter.java | 5 +++++ .../by/naxa/soundrecorder/services/RecordingService.java | 4 ---- app/src/main/res/layout/dialog_rename_file.xml | 8 ++++++++ app/src/main/res/values/array.xml | 2 +- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/by/naxa/soundrecorder/adapters/FileViewerAdapter.java b/app/src/main/java/by/naxa/soundrecorder/adapters/FileViewerAdapter.java index 1469c2fe..a69a392b 100644 --- a/app/src/main/java/by/naxa/soundrecorder/adapters/FileViewerAdapter.java +++ b/app/src/main/java/by/naxa/soundrecorder/adapters/FileViewerAdapter.java @@ -31,6 +31,8 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import org.w3c.dom.Text; + import by.naxa.soundrecorder.BuildConfig; import by.naxa.soundrecorder.DBHelper; import by.naxa.soundrecorder.R; @@ -240,6 +242,7 @@ public void removeOutOfApp(String filePath) { * rename a file */ public void rename(int position, String name) { + final String mFilePath = Paths.combine( Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC), Paths.SOUND_RECORDER_FOLDER, name); @@ -283,6 +286,8 @@ private void renameFileDialog(final int position) { LayoutInflater inflater = LayoutInflater.from(mContext); View view = inflater.inflate(R.layout.dialog_rename_file, null); + TextView text = (TextView)view.findViewById(R.id.textView); + text.setText(SettingsFragment.getFormat()); // TextView textView = (TextView) view.findViewById(R.id.textView); // textView.setText(SettingsFragment.getFormat()); diff --git a/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java b/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java index 6da229f3..5296100c 100644 --- a/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java +++ b/app/src/main/java/by/naxa/soundrecorder/services/RecordingService.java @@ -273,10 +273,6 @@ public void pauseRecording() { public void convertAudio() { - String saa = Paths.combine( - Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC), - Paths.SOUND_RECORDER_FOLDER, "My Recording_1.mp4"); - File source = new File(mFilePath); IConvertCallback callback = new IConvertCallback() { diff --git a/app/src/main/res/layout/dialog_rename_file.xml b/app/src/main/res/layout/dialog_rename_file.xml index dc9753c8..af73b96f 100644 --- a/app/src/main/res/layout/dialog_rename_file.xml +++ b/app/src/main/res/layout/dialog_rename_file.xml @@ -17,4 +17,12 @@ android:focusedByDefault="true" android:maxLines="1" /> + + \ No newline at end of file diff --git a/app/src/main/res/values/array.xml b/app/src/main/res/values/array.xml index c2aaa8cb..a504d10c 100644 --- a/app/src/main/res/values/array.xml +++ b/app/src/main/res/values/array.xml @@ -5,7 +5,7 @@ MP4 - MP3 + MP3(converted) AMR