From e5f5fbee9301d1a410b15c5193fc81f6cd11af9d Mon Sep 17 00:00:00 2001 From: casey langen Date: Sat, 29 Feb 2020 11:36:09 -0800 Subject: [PATCH 1/3] Upgraded to Android Studio 3.6. --- src/musikdroid/build.gradle | 2 +- src/musikdroid/gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/musikdroid/build.gradle b/src/musikdroid/build.gradle index cf20028a4..23a6b544c 100644 --- a/src/musikdroid/build.gradle +++ b/src/musikdroid/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.3' + classpath 'com.android.tools.build:gradle:3.6.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath 'com.google.gms:google-services:4.3.3' classpath 'io.fabric.tools:gradle:1.31.2' diff --git a/src/musikdroid/gradle/wrapper/gradle-wrapper.properties b/src/musikdroid/gradle/wrapper/gradle-wrapper.properties index e707104e8..3d8ea3ccd 100644 --- a/src/musikdroid/gradle/wrapper/gradle-wrapper.properties +++ b/src/musikdroid/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Aug 26 14:58:27 PDT 2019 +#Sat Feb 29 11:27:33 PST 2020 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip From 7a398e75a73bf4fbf00db77848e78c7f28ffa8e1 Mon Sep 17 00:00:00 2001 From: casey langen Date: Sat, 29 Feb 2020 12:09:09 -0800 Subject: [PATCH 2/3] Hopefully work around annoying prev() bug in ExoPlayer if track download takes too long. --- src/musikdroid/app/build.gradle | 12 ++++++------ .../impl/streaming/StreamingPlaybackService.kt | 14 +++++++++++--- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/musikdroid/app/build.gradle b/src/musikdroid/app/build.gradle index 9338e91f0..e184755b7 100644 --- a/src/musikdroid/app/build.gradle +++ b/src/musikdroid/app/build.gradle @@ -58,8 +58,8 @@ dependencies { exclude group: 'com.android.support', module: 'support-annotations' }) - implementation 'com.google.firebase:firebase-analytics:17.2.2' - implementation 'com.google.firebase:firebase-core:17.2.2' + implementation 'com.google.firebase:firebase-analytics:17.2.3' + implementation 'com.google.firebase:firebase-core:17.2.3' implementation(name:'android-taskrunner-0.5', ext:'aar') implementation(name:'exoplayer-extension-flac-release-v2', ext:'aar') @@ -67,8 +67,8 @@ dependencies { implementation 'org.slf4j:slf4j-android:1.7.21' - implementation "androidx.room:room-runtime:2.2.3" - kapt "androidx.room:room-compiler:2.2.3" + implementation "androidx.room:room-runtime:2.2.4" + kapt "androidx.room:room-compiler:2.2.4" implementation "androidx.lifecycle:lifecycle-runtime:2.2.0" implementation "androidx.lifecycle:lifecycle-extensions:2.2.0" @@ -86,7 +86,7 @@ dependencies { implementation 'io.reactivex.rxjava2:rxjava:2.2.16' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxkotlin:2.4.0' - implementation 'com.google.android.exoplayer:exoplayer:2.11.2' + implementation 'com.google.android.exoplayer:exoplayer:2.11.3' implementation 'com.google.android.exoplayer:extension-okhttp:2.11.2' implementation 'com.simplecityapps:recyclerview-fastscroll:2.0.0' implementation 'com.github.wooplr:Spotlight:1.3' @@ -94,7 +94,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.1.0' - implementation 'com.google.android.material:material:1.2.0-alpha04' + implementation 'com.google.android.material:material:1.2.0-alpha05' implementation 'androidx.media:media:1.1.0' implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1' diff --git a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/streaming/StreamingPlaybackService.kt b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/streaming/StreamingPlaybackService.kt index 681ca0ece..51006a5bb 100644 --- a/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/streaming/StreamingPlaybackService.kt +++ b/src/musikdroid/app/src/main/java/io/casey/musikcube/remote/service/playback/impl/streaming/StreamingPlaybackService.kt @@ -254,9 +254,17 @@ class StreamingPlaybackService(context: Context) : IPlaybackService { if (requestAudioFocus()) { cancelScheduledPausedSleep() - if (playContext.currentPlayer != null) { - if (playContext.currentPlayer?.position ?: 0 > PREV_TRACK_GRACE_PERIOD_MILLIS) { - playContext.currentPlayer?.position = 0 + playContext.currentPlayer?.let { player -> + if (player.position > PREV_TRACK_GRACE_PERIOD_MILLIS) { + /* if it takes too long to start up a player instance (e.g. we have to wait + for the backend to transcode, sometimes the duration is a negative number. + in that case we'll do this more heavy-weight reset */ + if (player.duration <= PREV_TRACK_GRACE_PERIOD_MILLIS) { + playAt(queuePosition) + } + else { + player.position = 0 + } return } } From 2e415a17b24176029a527701c5307f3a4ee3f0cb Mon Sep 17 00:00:00 2001 From: casey langen Date: Sat, 29 Feb 2020 17:15:16 -0800 Subject: [PATCH 3/3] Tweaked HttpServer to allow for multiple simultaenous connections, and be smart about waiting for existing blocking transcoders. --- src/plugins/server/HttpServer.cpp | 4 +-- src/plugins/server/Transcoder.cpp | 50 +++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/plugins/server/HttpServer.cpp b/src/plugins/server/HttpServer.cpp index d006ad3a8..f6b6383cc 100644 --- a/src/plugins/server/HttpServer.cpp +++ b/src/plugins/server/HttpServer.cpp @@ -294,9 +294,9 @@ bool HttpServer::Start() { httpServer = MHD_start_daemon( #if MHD_VERSION >= 0x00095300 - MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | ipVersion, + MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD | MHD_USE_THREAD_PER_CONNECTION | ipVersion, #else - MHD_USE_SELECT_INTERNALLY | ipVersion, + MHD_USE_SELECT_INTERNALLY | MHD_USE_THREAD_PER_CONNECTION | ipVersion, #endif context.prefs->GetInt(prefs::http_server_port.c_str(), defaults::http_server_port), nullptr, diff --git a/src/plugins/server/Transcoder.cpp b/src/plugins/server/Transcoder.cpp index fcc91a4cd..a5516d036 100644 --- a/src/plugins/server/Transcoder.cpp +++ b/src/plugins/server/Transcoder.cpp @@ -39,10 +39,16 @@ #include "Util.h" #include #include +#include +#include using namespace musik::core::sdk; using namespace boost::filesystem; +std::mutex transcoderMutex; +std::condition_variable waitForTranscode; +std::set runningBlockingTranscoders; + static IEncoder* getEncoder(Context& context, const std::string& format) { std::string extension = "." + format; return context.environment->GetEncoder(extension.c_str()); @@ -267,13 +273,45 @@ IDataStream* Transcoder::TranscodeAndWait( return context.environment->GetDataStream(uri.c_str(), OpenFlags::Read); } else { - IBlockingEncoder* dataStreamEncoder = dynamic_cast(encoder); - if (dataStreamEncoder) { - BlockingTranscoder blockingTranscoder( - context, dataStreamEncoder, uri, tempFilename, expectedFilename, bitrate); + IBlockingEncoder* blockingEncoder = dynamic_cast(encoder); + if (blockingEncoder) { + bool waitForExisting = false; + { + /* see if there's already a blocking transcoder running for the specified + uri. if there is, wait for it to complete. if there's not, add it to the + running set */ + std::unique_lock lock(transcoderMutex); + waitForExisting = runningBlockingTranscoders.find(uri) != runningBlockingTranscoders.end(); + if (waitForExisting) { + while (runningBlockingTranscoders.find(uri) != runningBlockingTranscoders.end()) { + waitForTranscode.wait(lock); + } + } + else { + runningBlockingTranscoders.insert(uri); + } + } - if (!blockingTranscoder.Transcode()) { - return nullptr; + if (!waitForExisting) { + BlockingTranscoder blockingTranscoder( + context, blockingEncoder, uri, tempFilename, expectedFilename, bitrate); + + bool success = blockingTranscoder.Transcode(); + + { + /* let anyone else waiting for a resource to be transcoding that we + finished. */ + std::unique_lock lock(transcoderMutex); + auto it = runningBlockingTranscoders.find(uri); + if (it != runningBlockingTranscoders.end()) { + runningBlockingTranscoders.erase(it); + } + waitForTranscode.notify_all(); + } + + if (!success) { + return nullptr; + } } }