Merge branch 'audiorecorder-3.3.23'

This commit is contained in:
Alexey Kuznetsov 2020-12-01 21:47:42 +03:00
commit 42da333102
7 changed files with 189 additions and 92 deletions

View file

@ -8,16 +8,16 @@ android {
defaultConfig {
applicationId "com.github.axet.audiorecorder"
minSdkVersion 9
targetSdkVersion 28
versionCode 347
versionName "3.3.22"
targetSdkVersion 29
versionCode 348
versionName "3.3.23"
}
signingConfigs {
release {
storeFile file(prop('RELEASE_STORE_FILE')?:'none')
storePassword prop('RELEASE_STORE_PASSWORD')
keyAlias prop('RELEASE_KEY_ALIAS')
keyPassword prop('RELEASE_KEY_PASSWORD')
storeFile file(project.findProperty('RELEASE_STORE_FILE')?:'none')
storePassword project.findProperty('RELEASE_STORE_PASSWORD')
keyAlias project.findProperty('RELEASE_KEY_ALIAS')
keyPassword project.findProperty('RELEASE_KEY_PASSWORD')
}
}
buildTypes {

View file

@ -40,6 +40,7 @@ import com.github.axet.androidlibrary.widgets.ErrorDialog;
import com.github.axet.androidlibrary.widgets.OpenFileDialog;
import com.github.axet.androidlibrary.widgets.SearchView;
import com.github.axet.audiolibrary.app.RawSamples;
import com.github.axet.audiolibrary.encoders.FormatWAV;
import com.github.axet.audiorecorder.R;
import com.github.axet.audiorecorder.app.AudioApplication;
import com.github.axet.audiorecorder.app.EncodingStorage;
@ -108,6 +109,7 @@ public class MainActivity extends AppCompatThemeActivity {
setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
setIndeterminate(false);
setMax(100);
setTitle(R.string.encoding_title);
this.info = info;
}
@ -181,22 +183,21 @@ public class MainActivity extends AppCompatThemeActivity {
}
}
public class EncodingDialog extends Handler {
public static class ProgressHandler extends Handler {
Context context;
Snackbar snackbar;
ProgressEncoding progress;
long cur;
long total;
Storage storage;
EncodingStorage encodings;
public EncodingDialog() {
public ProgressHandler() {
}
public void registerReceiver(Context context) {
this.context = context;
storage = new Storage(context);
encodings = ((AudioApplication) context.getApplicationContext()).encodings;
encodings = AudioApplication.from(context).encodings;
synchronized (encodings.handlers) {
encodings.handlers.add(this);
}
@ -238,52 +239,25 @@ public class MainActivity extends AppCompatThemeActivity {
} catch (JSONException e) {
throw new RuntimeException(e);
}
if (progress != null)
progress.setProgress(cur, total);
if (snackbar == null || !snackbar.isShownOrQueued()) {
snackbar = Snackbar.make(fab, printEncodings(targetUri), Snackbar.LENGTH_LONG);
snackbar.setDuration(Snackbar.LENGTH_INDEFINITE);
snackbar.getView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
progress = new ProgressEncoding(context, info);
progress.setTitle(R.string.encoding_title);
progress.setMessage(".../" + Storage.getName(context, targetUri));
progress.show();
progress.setProgress(cur, total);
EncodingService.startIfPending(context);
}
});
snackbar.show();
} else {
snackbar.setText(printEncodings(targetUri));
snackbar.show();
}
onUpdate(targetUri, info);
}
if (msg.what == EncodingStorage.DONE) {
Intent intent = (Intent) msg.obj;
final Uri targetUri = intent.getParcelableExtra("targetUri");
if (progress != null) {
progress.dismiss();
progress = null;
}
final Uri targetUri = intent.getParcelableExtra("targetUri");
recordings.load(false, null);
if (snackbar != null && snackbar.isShownOrQueued()) {
snackbar.setText(printEncodings(targetUri));
snackbar.setDuration(Snackbar.LENGTH_SHORT);
snackbar.show();
}
RecordingService.startIfPending(context);
onDone(targetUri);
}
if (msg.what == EncodingStorage.EXIT) {
if (progress != null) {
progress.dismiss();
progress = null;
}
hide();
RecordingService.startIfPending(context);
onExit();
}
if (msg.what == EncodingStorage.ERROR) {
Intent intent = (Intent) msg.obj;
@ -299,11 +273,34 @@ public class MainActivity extends AppCompatThemeActivity {
throw new RuntimeException(e);
}
Throwable e = (Throwable) intent.getSerializableExtra("e");
Error(in, info, e);
RecordingService.startIfPending(context);
onError(in, info, e);
}
}
public void onUpdate(Uri targetUri, RawSamples.Info info) {
}
public void onError(File in, RawSamples.Info info, Throwable e) {
Error(in, info, e);
RecordingService.startIfPending(context);
}
public void onExit() {
hide();
RecordingService.startIfPending(context);
}
public void onDone(Uri targetUri) {
RecordingService.startIfPending(context);
}
public void show(Uri targetUri, RawSamples.Info info) {
progress = new ProgressEncoding(context, info);
progress.setMessage(".../" + Storage.getName(context, targetUri));
progress.show();
progress.setProgress(cur, total);
}
public void onPause() {
if (progress != null)
progress.onPause(cur);
@ -334,7 +331,8 @@ public class MainActivity extends AppCompatThemeActivity {
d.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
EncodingService.saveAsWAV(context, in, d.getCurrentPath(), info);
File to = storage.getNewFile(d.getCurrentPath(), FormatWAV.EXT);
EncodingService.saveAsWAV(context, in, to, info);
}
});
d.show();
@ -345,6 +343,62 @@ public class MainActivity extends AppCompatThemeActivity {
}
public void hide() {
if (progress != null) {
progress.dismiss();
progress = null;
}
}
}
public class EncodingDialog extends ProgressHandler {
Snackbar snackbar;
public EncodingDialog() {
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == EncodingStorage.UPDATE) {
Intent intent = (Intent) msg.obj;
final Uri targetUri = intent.getParcelableExtra("targetUri");
final RawSamples.Info info;
try {
info = new RawSamples.Info(intent.getStringExtra("info"));
} catch (JSONException e) {
throw new RuntimeException(e);
}
if (snackbar == null || !snackbar.isShownOrQueued()) {
snackbar = Snackbar.make(fab, printEncodings(targetUri), Snackbar.LENGTH_LONG);
snackbar.setDuration(Snackbar.LENGTH_INDEFINITE);
snackbar.getView().setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
show(targetUri, info);
EncodingService.startIfPending(context);
}
});
snackbar.show();
} else {
snackbar.setText(printEncodings(targetUri));
snackbar.show();
}
}
if (msg.what == EncodingStorage.DONE) {
Intent intent = (Intent) msg.obj;
final Uri targetUri = intent.getParcelableExtra("targetUri");
recordings.load(false, null);
if (snackbar != null && snackbar.isShownOrQueued()) {
snackbar.setText(printEncodings(targetUri));
snackbar.setDuration(Snackbar.LENGTH_SHORT);
snackbar.show();
}
}
}
@Override
public void hide() {
super.hide();
if (snackbar != null) {
snackbar.dismiss();
snackbar = null;

View file

@ -45,7 +45,6 @@ import com.github.axet.androidlibrary.widgets.Toast;
import com.github.axet.audiolibrary.app.RawSamples;
import com.github.axet.audiolibrary.app.Sound;
import com.github.axet.audiolibrary.encoders.Factory;
import com.github.axet.audiolibrary.encoders.FormatWAV;
import com.github.axet.audiolibrary.widgets.PitchView;
import com.github.axet.audiorecorder.BuildConfig;
import com.github.axet.audiorecorder.R;
@ -100,6 +99,8 @@ public class RecordingActivity extends AppCompatThemeActivity {
RecordingReceiver receiver;
MainActivity.ProgressHandler progress;
AlertDialog muted;
Handler handler = new Handler() {
@Override
@ -324,10 +325,15 @@ public class RecordingActivity extends AppCompatThemeActivity {
public void Error(Throwable e) {
Log.e(TAG, "error", e);
Error(toMessage(e));
Error(recording.storage.getTempRecording(), toMessage(e));
}
public void Error(String msg) {
public void Error(File in, Throwable e) {
Log.e(TAG, "error", e);
Error(in, toMessage(e));
}
public void Error(File in, String msg) {
ErrorDialog builder = new ErrorDialog(this, msg);
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
@ -341,7 +347,6 @@ public class RecordingActivity extends AppCompatThemeActivity {
finish();
}
});
final File in = recording.storage.getTempRecording();
if (in.length() > 0) {
builder.setNeutralButton(R.string.save_as_wav, new DialogInterface.OnClickListener() {
@Override
@ -350,7 +355,9 @@ public class RecordingActivity extends AppCompatThemeActivity {
d.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
EncodingService.saveAsWAV(RecordingActivity.this, recording.storage.getTempRecording(), d.getCurrentPath(), recording.getInfo());
File to = new File(d.getCurrentPath(), Storage.getName(RecordingActivity.this, recording.targetUri));
recording.targetUri = Uri.fromFile(to);
EncodingService.saveAsWAV(RecordingActivity.this, recording.storage.getTempRecording(), to, recording.getInfo());
}
});
d.show();
@ -624,6 +631,9 @@ public class RecordingActivity extends AppCompatThemeActivity {
if (editSample != -1)
edit(true, false);
}
if (progress != null)
progress.onResume();
}
@Override
@ -633,6 +643,8 @@ public class RecordingActivity extends AppCompatThemeActivity {
recording.updateBufferSize(true);
editPlay(false);
pitch.stop();
if (progress != null)
progress.onPause();
}
void stopRecording(String status) {
@ -887,6 +899,11 @@ public class RecordingActivity extends AppCompatThemeActivity {
receiver = null;
}
if (progress != null) {
progress.close();
progress = null;
}
RecordingService.stopRecording(this);
if (pscl != null) {
@ -985,9 +1002,39 @@ public class RecordingActivity extends AppCompatThemeActivity {
return;
}
EncodingService.startEncoding(this, in, recording.targetUri, recording.getInfo());
final File encoding = EncodingService.startEncoding(this, in, recording.targetUri, recording.getInfo());
finish();
if (recordSoundIntent != null) {
if (progress != null)
progress.close();
progress = new MainActivity.ProgressHandler() {
@Override
public void onDone(Uri targetUri) {
super.onDone(targetUri);
if (targetUri.equals(recording.targetUri))
done.run();
}
@Override
public void onExit() {
super.onExit();
done.run();
}
@Override
public void onError(File in, RawSamples.Info info, Throwable e) {
if (in.equals(encoding))
RecordingActivity.this.Error(encoding, e); // show error for current encoding
else
Error(in, info, e); // show error for any encoding
}
};
progress.registerReceiver(this);
progress.show(recording.targetUri, recording.getInfo());
progress.progress.setCancelable(false);
} else {
done.run();
}
}
@Override

View file

@ -219,7 +219,6 @@ public class EncodingStorage extends HashMap<File, EncodingStorage.Info> {
}
public void saveAsWAV(File in, File out, RawSamples.Info info) {
out = storage.getNewFile(out, FormatWAV.EXT);
OnFlyEncoding fly = new OnFlyEncoding(storage, out, info);
encoder = new FileEncoder(storage.getContext(), in, fly);
encoding(encoder, fly, info, new Runnable() {

View file

@ -89,7 +89,7 @@ public class EncodingService extends PersistentService {
stop(context, new Intent(context, EncodingService.class));
}
public static void startEncoding(Context context, File in, Uri targetUri, RawSamples.Info info) {
public static File startEncoding(Context context, File in, Uri targetUri, RawSamples.Info info) {
try {
EncodingStorage encodings = ((AudioApplication) context.getApplicationContext()).encodings;
in = encodings.save(in, targetUri, info);
@ -98,6 +98,7 @@ public class EncodingService extends PersistentService {
.putExtra("targetUri", targetUri)
.putExtra("info", info.save().toString())
);
return in;
} catch (JSONException e) {
throw new RuntimeException(e);
}

View file

@ -1,5 +1,5 @@
<resources>
<string name="app_name">Gravador de Áudio</string>
<string name="app_name">Audio Recorder</string>
<string-array name="sample_rate_text">
<item>48 kHz</item>
@ -13,13 +13,13 @@
<string-array name="source_text">
<item>Mic</item>
<item>Unprocessed</item>
<item>Não processado</item>
<item>Bluetooth</item>
</string-array>
<string-array name="themes_text">
<item>Claro</item>
<item>Escuro</item>
<item>Tema Claro</item>
<item>Tema Escuro</item>
</string-array>
<string-array name="channels_text">
@ -27,52 +27,52 @@
<item>Estéreo</item>
</string-array>
<string name="no_folder_app">Não foi encontrado um aplicativo para explorar arquivos</string>
<string name="no_folder_app">Não foi encontrado nenhum aplicativo para explorar os arquivos</string>
<string name="hold_by_call">pausado (chamada atendida)</string>
<string name="recording_status_recording">gravando</string>
<string name="recording_status_encoding">codificando</string>
<string name="recording_status_pause">pausado</string>
<string name="recording_status_edit">editando</string>
<string name="confirm_cancel">Confirme o cancelamento</string>
<string name="confirm_cancel">Deseja cancelar</string>
<string name="encoding_title">Codificando...</string>
<string name="recording_title">Gravando</string>
<string name="pause_title">Pausado...</string>
<string name="recording_title">Gravando</string>
<string name="open_recording_folder">Abrir pasta das gravações</string>
<string name="recording_list_is_empty">A lista de gravações está vazia\n\nToque no ícone de microfone para começar a gravar</string>
<string name="record_button">Record</string>
<string name="cut_button">Cut</string>
<string name="stop_button">Stop</string>
<string name="cancel_button">Cancel</string>
<string name="pause_button">Pause</string>
<string name="recording_list_is_empty">A lista das gravações está vazia\n\nToque no ícone do microfone para começar a gravar</string>
<string name="record_button">Gravar</string>
<string name="cut_button">Cortar</string>
<string name="stop_button">Parar</string>
<string name="cancel_button">Cancelar</string>
<string name="pause_button">Pausar</string>
<string name="pref_storage_title">Destino das gravações</string>
<string name="pref_storage_title">Pasta das gravações</string>
<string name="pref_rate_title">Taxa de amostragem</string>
<string name="pref_encoding_title">Codificação</string>
<string name="pref_encoding_summary">Formato de saída do arquivo (.wav, .mp3, etc.)</string>
<string name="pref_mode_title">Modo</string>
<string name="pref_mode_summary">Canais a gravar</string>
<string name="pref_mode_title">Canais de áudio</string>
<string name="pref_mode_summary">Canais de gravação</string>
<string name="pref_nameformat_title">Formato do nome de arquivo</string>
<string name="pref_pausecalls_title">Pausar durante chamadas</string>
<string name="pref_pausecalls_title">Pausar durante a chamada</string>
<string name="pref_pausecalls_summary">e voltar a gravar quando a chamada for desligada</string>
<string name="pref_silence_title">Modo silencioso</string>
<string name="pref_silence_summary">Silenciar o aparelho durante a gravação</string>
<string name="pref_silence_summary">Ativar o \'modo silencioso\' durante a gravação</string>
<string name="pref_lockscreen_title">Controle da tela bloqueada</string>
<string name="pref_lockscreen_summary">Mostrar controles quando a tela estiver bloqueada</string>
<string name="pref_theme_title">Tema do app</string>
<string name="pref_lockscreen_summary">Mostrar os controles quando a tela estiver bloqueada</string>
<string name="pref_theme_title">Tema do App</string>
<string name="pref_theme_summary">Definir o tema (claro ou escuro)</string>
<string name="pref_application">Application</string>
<string name="pref_recordings">Recordings</string>
<string name="pref_fly_title">Encoding on Fly</string>
<string name="pref_fly_summary">Encoding on fly disable editing, and crash recovery</string>
<string name="hold_by_bluetooth">pause (bluetooth disconnected)</string>
<string name="menu_search">Search</string>
<string name="save_as_wav">Save as WAV</string>
<string name="auto_close">Auto close in (%1$d)</string>
<string name="mic_muted_error">Mic muted</string>
<string name="mic_muted_pie">Android Pie and above prevent idle background apps from using microphone. Please disable selinux or install previous android version!</string>
<string name="mic_paused">Mic paused by OS, recording time is less then data recorded, check if you device supports background recording or it is fast enougth for selected settings</string>
<string name="tile_start_recording">Start Recording</string>
<string name="tile_stop_recording">Stop Recording</string>
<string name="encoding_optimization">Background encoding paused due to android Battery Optimization settings, please allow this application work in background</string>
<string name="pref_application">Aplicativo</string>
<string name="pref_recordings">Gravações</string>
<string name="pref_fly_title">Codificação em tempo real</string>
<string name="pref_fly_summary">Ativando codificação em tempo real desabilitará a edição e recuperação após a falha</string>
<string name="hold_by_bluetooth">pausado (bluetooth desconectado)</string>
<string name="menu_search">Pesquisar</string>
<string name="save_as_wav">Salvar como WAV</string>
<string name="auto_close">Auto-fechar em (%1$d)</string>
<string name="mic_muted_error">Mic silenciado</string>
<string name="mic_muted_pie">Android 9 (Pie) e mais recente impedem que os Apps em segundo plano utilizem o microfone. Solução: ou desabilitar o SeLinux ou usar a versão anterior do Android!</string>
<string name="mic_paused">Microfone foi pausado pelo Android, o tempo de gravação é menor do que o conteúdo gravado. Verifique se seu dispositivo suporta gravação em segundo plano ou se é o suficiente rápido para utilizar as configurações selecionadas</string>
<string name="tile_start_recording">Iniciar Gravação</string>
<string name="tile_stop_recording">Parar a Gravação</string>
<string name="encoding_optimization">Codificação em segundo plano foi pausada devido a configuração do Android de otimização da bateria, por favor permita que o App funcione em segundo plano</string>
<string name="per_second">/s</string>
</resources>

View file

@ -21,7 +21,3 @@ allprojects {
task clean(type: Delete) {
delete rootProject.buildDir
}
def prop(String name) {
project.hasProperty(name) ? project.getProperty(name) : null
}