diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 1ecf9a3..23ea73b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -51,7 +51,7 @@ { if (!StreamingService.isStreaming()) { - if (sharedPreferences.getString("RtmpUrl", "").isEmpty() || sharedPreferences.getString("RtmpKey", "").isEmpty()) { + if (sharedPreferences.getString("StreamRtmpUrl", "").isEmpty() || sharedPreferences.getString("StreamRtmpKey", "").isEmpty()) { Toast.makeText(this, getString(R.string.rtmp_settings_empty), Toast.LENGTH_LONG).show(); Intent intent = new Intent(v.getContext(), SettingsActivity.class); v.getContext().startActivity(intent); diff --git a/app/src/main/java/com/fpvout/digiview/SettingsActivity.java b/app/src/main/java/com/fpvout/digiview/SettingsActivity.java index 1cf20f9..6c70174 100644 --- a/app/src/main/java/com/fpvout/digiview/SettingsActivity.java +++ b/app/src/main/java/com/fpvout/digiview/SettingsActivity.java @@ -10,6 +10,8 @@ import androidx.preference.ListPreference; import androidx.preference.PreferenceFragmentCompat; +import com.fpvout.digiview.streaming.StreamAudioSource; + import java.util.ArrayList; import java.util.Arrays; @@ -48,13 +50,16 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.root_preferences, rootKey); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - ListPreference audioSourcePreference = findPreference("AudioSource"); + ListPreference audioSourcePreference = findPreference("StreamAudioSource"); ArrayList entries = new ArrayList<>(Arrays.asList(audioSourcePreference.getEntries())); ArrayList entryValues = new ArrayList<>(Arrays.asList(audioSourcePreference.getEntryValues())); - entries.add(getString(R.string.audio_source_internal)); - entryValues.add("internal"); + entries.add(getString(R.string.stream_audio_source_performance)); + entryValues.add(StreamAudioSource.PERFORMANCE); + + entries.add(getString(R.string.stream_audio_source_internal)); + entryValues.add(StreamAudioSource.INTERNAL); audioSourcePreference.setEntries(entries.toArray(new CharSequence[0])); audioSourcePreference.setEntryValues(entryValues.toArray(new CharSequence[0])); diff --git a/app/src/main/java/com/fpvout/digiview/streaming/StreamAudioBitrate.java b/app/src/main/java/com/fpvout/digiview/streaming/StreamAudioBitrate.java new file mode 100644 index 0000000..e120e1a --- /dev/null +++ b/app/src/main/java/com/fpvout/digiview/streaming/StreamAudioBitrate.java @@ -0,0 +1,9 @@ +package com.fpvout.digiview.streaming; + +public class StreamAudioBitrate { + public static final String DEFAULT = "128"; + + public static int getBitrate(String value) { + return Integer.parseInt(value) * 1024; + } +} diff --git a/app/src/main/java/com/fpvout/digiview/streaming/StreamAudioSampleRate.java b/app/src/main/java/com/fpvout/digiview/streaming/StreamAudioSampleRate.java new file mode 100644 index 0000000..5404322 --- /dev/null +++ b/app/src/main/java/com/fpvout/digiview/streaming/StreamAudioSampleRate.java @@ -0,0 +1,28 @@ +package com.fpvout.digiview.streaming; + +public class StreamAudioSampleRate { + public static final String DEFAULT = "44100hz"; + + public static int getSampleRate(String value) { + switch (value) { + case "8khz": + return 8000; + case "11025hz": + return 11025; + case "16khz": + return 16000; + case "22050hz": + return 22050; + case "32000hz": + return 32000; + case DEFAULT: + return 44100; + case "48khz": + return 48000; + case "96khz": + return 96000; + } + + return -1; + } +} diff --git a/app/src/main/java/com/fpvout/digiview/streaming/StreamAudioSource.java b/app/src/main/java/com/fpvout/digiview/streaming/StreamAudioSource.java new file mode 100644 index 0000000..21e7ab1 --- /dev/null +++ b/app/src/main/java/com/fpvout/digiview/streaming/StreamAudioSource.java @@ -0,0 +1,26 @@ +package com.fpvout.digiview.streaming; + +import android.media.MediaRecorder; + +public class StreamAudioSource { + public static final String DEFAULT = "default"; + public static final String INTERNAL = "internal"; + public static final String PERFORMANCE = "performance"; + + public static int getAudioSource(String value) { + switch (value) { + case DEFAULT: + return MediaRecorder.AudioSource.DEFAULT; + case "mic": + return MediaRecorder.AudioSource.MIC; + case "cam": + return MediaRecorder.AudioSource.CAMCORDER; + case "communication": + return MediaRecorder.AudioSource.VOICE_COMMUNICATION; + case PERFORMANCE: + return MediaRecorder.AudioSource.VOICE_PERFORMANCE; + } + + return -1; + } +} diff --git a/app/src/main/java/com/fpvout/digiview/streaming/StreamBitrate.java b/app/src/main/java/com/fpvout/digiview/streaming/StreamBitrate.java new file mode 100644 index 0000000..eae699e --- /dev/null +++ b/app/src/main/java/com/fpvout/digiview/streaming/StreamBitrate.java @@ -0,0 +1,9 @@ +package com.fpvout.digiview.streaming; + +public class StreamBitrate { + public static final String DEFAULT = "2500"; + + public static int getBitrate(String value) { + return Integer.parseInt(value) * 1024; + } +} diff --git a/app/src/main/java/com/fpvout/digiview/streaming/StreamFramerate.java b/app/src/main/java/com/fpvout/digiview/streaming/StreamFramerate.java new file mode 100644 index 0000000..3087404 --- /dev/null +++ b/app/src/main/java/com/fpvout/digiview/streaming/StreamFramerate.java @@ -0,0 +1,9 @@ +package com.fpvout.digiview.streaming; + +public class StreamFramerate { + public static final String DEFAULT = "60"; + + public static int getFramerate(String value) { + return Integer.parseInt(value); + } +} diff --git a/app/src/main/java/com/fpvout/digiview/streaming/StreamResolution.java b/app/src/main/java/com/fpvout/digiview/streaming/StreamResolution.java new file mode 100644 index 0000000..fb74a43 --- /dev/null +++ b/app/src/main/java/com/fpvout/digiview/streaming/StreamResolution.java @@ -0,0 +1,37 @@ +package com.fpvout.digiview.streaming; + +public class StreamResolution { + public static final String DEFAULT = "720p"; + private final int width; + private final int height; + + private StreamResolution(int width, int height) { + this.width = width; + this.height = height; + } + + public static StreamResolution getResolution(String value) { + switch (value) { + case "240p": + return new StreamResolution(426, 240); + case "360p": + return new StreamResolution(640, 360); + case "480p": + return new StreamResolution(854, 480); + case DEFAULT: + return new StreamResolution(1280, 720); + case "1080p": + return new StreamResolution(1920, 1080); + } + + return null; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } +} diff --git a/app/src/main/java/com/fpvout/digiview/StreamingService.java b/app/src/main/java/com/fpvout/digiview/streaming/StreamingService.java similarity index 68% rename from app/src/main/java/com/fpvout/digiview/StreamingService.java rename to app/src/main/java/com/fpvout/digiview/streaming/StreamingService.java index 58c4bfc..2f819d6 100644 --- a/app/src/main/java/com/fpvout/digiview/StreamingService.java +++ b/app/src/main/java/com/fpvout/digiview/streaming/StreamingService.java @@ -1,4 +1,4 @@ -package com.fpvout.digiview; +package com.fpvout.digiview.streaming; import android.app.Notification; import android.app.NotificationChannel; @@ -32,6 +32,7 @@ public class StreamingService extends Service { private static RtmpDisplay rtmpDisplayBase; private static int dpi; private String endpoint; + @Nullable @Override public IBinder onBind(Intent intent) { @@ -54,7 +55,7 @@ public void onCreate() { @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "Start"); - endpoint = String.format("%s/%s", sharedPreferences.getString("RtmpUrl", ""), sharedPreferences.getString("RtmpKey", "")); + endpoint = String.format("%s/%s", sharedPreferences.getString("StreamRtmpUrl", ""), sharedPreferences.getString("StreamRtmpKey", "")); prepareStreaming(); startStreaming(); @@ -64,31 +65,45 @@ public int onStartCommand(Intent intent, int flags, int startId) { private void prepareStreaming() { stopStreaming(); rtmpDisplayBase = new RtmpDisplay(appContext, true, connectChecker); - if (!sharedPreferences.getString("RtmpUsername", "").isEmpty() && !sharedPreferences.getString("RtmpPassword", "").isEmpty()) { - rtmpDisplayBase.setAuthorization(sharedPreferences.getString("RtmpUsername", ""), sharedPreferences.getString("RtmpPassword", "")); + if (!sharedPreferences.getString("StreamRtmpUsername", "").isEmpty() && !sharedPreferences.getString("StreamRtmpPassword", "").isEmpty()) { + rtmpDisplayBase.setAuthorization(sharedPreferences.getString("StreamRtmpUsername", ""), sharedPreferences.getString("StreamRtmpPassword", "")); } rtmpDisplayBase.setIntentResult(mediaProjectionResultCode, mediaProjectionData); } private void startStreaming() { if (!rtmpDisplayBase.isStreaming()) { + StreamResolution streamResolution = StreamResolution.getResolution(sharedPreferences.getString("StreamResolution", StreamResolution.DEFAULT)); if (rtmpDisplayBase.prepareVideo( - Integer.parseInt(sharedPreferences.getString("OutputWidth", "1280")), - Integer.parseInt(sharedPreferences.getString("OutputHeight", "720")), - Integer.parseInt(sharedPreferences.getString("OutputFramerate", "60")), - Integer.parseInt(sharedPreferences.getString("OutputBitrate", "1200")) * 1024, + streamResolution.getWidth(), + streamResolution.getHeight(), + StreamFramerate.getFramerate(sharedPreferences.getString("StreamFramerate", StreamFramerate.DEFAULT)), + StreamBitrate.getBitrate(sharedPreferences.getString("StreamBitrate", StreamBitrate.DEFAULT)), 0, dpi )) { boolean audioInitialized; - if (sharedPreferences.getString("AudioSource", "0").equals("internal") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - audioInitialized = rtmpDisplayBase.prepareInternalAudio(64 * 1024, 32000, true, false, false); + if (sharedPreferences.getString("StreamAudioSource", StreamAudioSource.DEFAULT).equals(StreamAudioSource.INTERNAL) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + audioInitialized = rtmpDisplayBase.prepareInternalAudio( + StreamAudioBitrate.getBitrate(sharedPreferences.getString("StreamAudioBitrate", StreamAudioBitrate.DEFAULT)), + StreamAudioSampleRate.getSampleRate(sharedPreferences.getString("StreamAudioSampleRate", StreamAudioSampleRate.DEFAULT)), + sharedPreferences.getBoolean("StreamAudioStereo", true), + false, + false + ); } else { - audioInitialized = rtmpDisplayBase.prepareAudio(Integer.parseInt(sharedPreferences.getString("AudioSource", "0")), 64 * 1024, 32000, false, false, false); + audioInitialized = rtmpDisplayBase.prepareAudio( + StreamAudioSource.getAudioSource(sharedPreferences.getString("StreamAudioSource", StreamAudioSource.DEFAULT)), + StreamAudioBitrate.getBitrate(sharedPreferences.getString("StreamAudioBitrate", StreamAudioBitrate.DEFAULT)), + StreamAudioSampleRate.getSampleRate(sharedPreferences.getString("StreamAudioSampleRate", StreamAudioSampleRate.DEFAULT)), + sharedPreferences.getBoolean("StreamAudioStereo", true), + false, + false + ); } if (audioInitialized) { - if (!sharedPreferences.getBoolean("RecordAudio", true)) { + if (!sharedPreferences.getBoolean("StreamRecordAudio", true)) { rtmpDisplayBase.disableAudio(); } else { rtmpDisplayBase.enableAudio(); @@ -146,8 +161,8 @@ public static void init(Context context, ConnectCheckerRtmp connectCheckerRtmp) if (rtmpDisplayBase == null) { sharedPreferences = PreferenceManager.getDefaultSharedPreferences(appContext); rtmpDisplayBase = new RtmpDisplay(appContext, true, connectChecker); - if (!sharedPreferences.getString("RtmpUsername", "").isEmpty() && !sharedPreferences.getString("RtmpPassword", "").isEmpty()) { - rtmpDisplayBase.setAuthorization(sharedPreferences.getString("RtmpUsername", ""), sharedPreferences.getString("RtmpPassword", "")); + if (!sharedPreferences.getString("StreamRtmpUsername", "").isEmpty() && !sharedPreferences.getString("StreamRtmpPassword", "").isEmpty()) { + rtmpDisplayBase.setAuthorization(sharedPreferences.getString("StreamRtmpUsername", ""), sharedPreferences.getString("StreamRtmpPassword", "")); } } } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 583fa19..3a8f651 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -41,23 +41,27 @@ Open-Source Lizenz MIT Lizenz Streaming - RTMP Url - RTMP Key - RTMP Username - RTMP Password - Record audio - Audio source - Default - Mic - Camera - Communication - Performance - Internal audio - Output Width - Output Height - Output Framerate - Output Bitrate + RTMP Url + RTMP Key + RTMP Username + RTMP Password + Record audio + Audio source + Default + Mic + Camera + Communication + Performance + Internal audio + Output Resolution + Output Framerate + Output Max Bitrate Failed to connect to RTMP server RTMP authentication failed Please, check your streaming RTMP URL and Key + Audio recording can be muted during live + Stereo audio + Only if your device or the audio source supports it + Audio sample rate + Audio bitrate \ No newline at end of file diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 05ef891..37c61f1 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -40,23 +40,27 @@ Licencia Open-Source Licencia MIT Streaming - RTMP Url - RTMP Key - RTMP Username - RTMP Password - Record audio - Audio source - Default - Mic - Camera - Communication - Performance - Internal audio - Output Width - Output Height - Output Framerate - Output Bitrate + RTMP Url + RTMP Key + RTMP Username + RTMP Password + Record audio + Audio source + Default + Mic + Camera + Communication + Performance + Internal audio + Output Resolution + Output Framerate + Output Max Bitrate Failed to connect to RTMP server RTMP authentication failed Please, check your streaming RTMP URL and Key + Audio recording can be muted during live + Stereo audio + Only if your device or the audio source supports it + Audio sample rate + Audio bitrate \ No newline at end of file diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 82c3e4a..a909ceb 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -38,23 +38,27 @@ License Open-Source License MIT Streaming - RTMP Url - RTMP Key - RTMP Username - RTMP Password - Enregistrer le son - Source audio - Par défaut - Mic - Camera - Communication - Performance - Audio interne - Output Width - Output Height - Output Framerate - Output Bitrate + RTMP Url + RTMP Key + RTMP Username + RTMP Password + Enregistrer le son + Source audio + Par défaut + Mic + Camera + Communication + Performance + Audio interne + Output Resolution + Output Framerate + Output Max Bitrate Failed to connect to RTMP server RTMP authentication failed Please, check your streaming RTMP URL and Key + Audio recording can be muted during live + Stereo audio + Only if your device or the audio source supports it + Audio sample rate + Audio bitrate \ No newline at end of file diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 5f54249..7972209 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -40,24 +40,28 @@ Licença Open-Source Licença MIT Streaming - RTMP Url - RTMP Key - RTMP Username - RTMP Password - Record audio - Audio source - Default - Mic - Camera - Communication - Performance - Internal audio - Output Width - Output Height - Output Framerate - Output Bitrate + RTMP Url + RTMP Key + RTMP Username + RTMP Password + Record audio + Audio source + Default + Mic + Camera + Communication + Performance + Internal audio + Output Resolution + Output Framerate + Output Max Bitrate Failed to connect to RTMP server RTMP authentication failed Please, check your streaming RTMP URL and Key + Audio recording can be muted during live + Stereo audio + Only if your device or the audio source supports it + Audio sample rate + Audio bitrate \ No newline at end of file diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index 08ebbfc..304fb8b 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -40,24 +40,28 @@ 开源证书 MIT License Streaming - RTMP Url - RTMP Key - RTMP Username - RTMP Password - Record audio - Audio source - Default - Mic - Camera - Communication - Performance - Internal audio - Output Width - Output Height - Output Framerate - Output Bitrate + RTMP Url + RTMP Key + RTMP Username + RTMP Password + Record audio + Audio source + Default + Mic + Camera + Communication + Performance + Internal audio + Output Resolution + Output Framerate + Output Max Bitrate Failed to connect to RTMP server RTMP authentication failed Please, check your streaming RTMP URL and Key + Audio recording can be muted during live + Stereo audio + Only if your device or the audio source supports it + Audio sample rate + Audio bitrate diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index c91eeee..734d921 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -15,19 +15,127 @@ legacy_buffered - - @string/audio_source_default - @string/audio_source_mic - @string/audio_source_cam - @string/audio_source_communication - @string/audio_source_performance - - - - 0 - 1 - 5 - 7 - 10 + + @string/stream_audio_source_default + @string/stream_audio_source_mic + @string/stream_audio_source_cam + @string/stream_audio_source_communication + + + + default + mic + cam + communication + + + + 240p + 360p + 480p + 720p (default) + 1080p + + + + 240p + 360p + 480p + 720p + 1080p + + + + 15 fps + 24 fps + 25 fps + 30 fps + 60 fps (default) + + + + 15 + 24 + 25 + 30 + 60 + + + + 300 kbps + 500 kbps + 700 kbps + 1000 kbps + 1500 kbps + 2000 kbps + 2500 kbps (default) + 3500 kbps + 4000 kbps + 5000 kbps + 6000 kbps + 7000 kbps + 8000 kbps + 10000 kbps + 15000 kbps + 20000 kbps + 25000 kbps + + + + 300 + 500 + 700 + 1000 + 1500 + 2000 + 2500 + 3500 + 4000 + 5000 + 6000 + 7000 + 8000 + 10000 + 15000 + 20000 + 25000 + + + + 8 KHz + 11025 Hz + 16 KHz + 22050 Hz + 32000 Hz + 44100 Hz (default) + 48 KHz + 96 KHz + + + + 8khz + 11025hz + 16khz + 22050hz + 32000hz + 44100hz + 48khz + 96khz + + + + 64 kbps + 96 kbps + 128 kbps (default) + 192 kbps + 320 kbps + + + + 64 + 96 + 128 + 192 + 320 \ 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 6cecd38..9949102 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -41,24 +41,28 @@ Open-Source License MIT License Streaming - RTMP Url - RTMP Key - RTMP Username - RTMP Password - Record audio - Audio source - Default - Mic - Camera - Communication - Performance - Internal audio - Output Width - Output Height - Output Framerate - Output Bitrate + RTMP Url + RTMP Key + RTMP Username + RTMP Password + Record audio + Audio source + Default + Mic + Camera + Communication + Performance + Internal audio + Output Resolution + Output Framerate + Output Max Bitrate Failed to connect to RTMP server RTMP authentication failed Please, check your streaming RTMP URL and Key + Audio recording can be muted during live + Stereo audio + Only if your device or the audio source supports it + Audio sample rate + Audio bitrate \ No newline at end of file diff --git a/app/src/main/res/xml/root_preferences.xml b/app/src/main/res/xml/root_preferences.xml index ce90623..20df726 100644 --- a/app/src/main/res/xml/root_preferences.xml +++ b/app/src/main/res/xml/root_preferences.xml @@ -50,58 +50,81 @@ + app:key="StreamRtmpKey" + app:title="@string/stream_rtmp_key" /> + app:key="StreamRtmpPassword" + app:title="@string/stream_rtmp_password" /> - - - - - + app:key="StreamRecordAudio" + app:defaultValue="true" + app:title="@string/stream_record_audio" + app:summary="@string/stream_record_audio_summary" /> + + + + + +