diff --git a/app/src/main/java/com/novage/demo/viewmodel/ExoPlayerViewModel.kt b/app/src/main/java/com/novage/demo/viewmodel/ExoPlayerViewModel.kt index f6f1775..0b67b45 100644 --- a/app/src/main/java/com/novage/demo/viewmodel/ExoPlayerViewModel.kt +++ b/app/src/main/java/com/novage/demo/viewmodel/ExoPlayerViewModel.kt @@ -37,8 +37,8 @@ class ExoPlayerViewModel(application: Application) : AndroidViewModel(applicatio fun setupP2PML() { p2pml = P2PMediaLoader( - readyCallback = { initializePlayback() }, - onReadyErrorCallback = { onReadyError(it) }, + onP2PReadyCallback = { initializePlayback() }, + onP2PReadyErrorCallback = { onReadyError(it) }, coreConfigJson = "{\"swarmId\":\"TEST_KOTLIN\"}", serverPort = 8081, ) diff --git a/p2pml/src/main/java/com/novage/p2pml/P2PMediaLoader.kt b/p2pml/src/main/java/com/novage/p2pml/P2PMediaLoader.kt index 99423ee..954b6bf 100644 --- a/p2pml/src/main/java/com/novage/p2pml/P2PMediaLoader.kt +++ b/p2pml/src/main/java/com/novage/p2pml/P2PMediaLoader.kt @@ -6,8 +6,8 @@ import androidx.media3.exoplayer.ExoPlayer import com.novage.p2pml.Constants.CORE_FILE_URL import com.novage.p2pml.Constants.CUSTOM_FILE_URL import com.novage.p2pml.Constants.QueryParams.MANIFEST -import com.novage.p2pml.interop.OnErrorCallback -import com.novage.p2pml.interop.P2PReadyCallback +import com.novage.p2pml.interop.OnP2PReadyCallback +import com.novage.p2pml.interop.OnP2PReadyErrorCallback import com.novage.p2pml.parser.HlsManifestParser import com.novage.p2pml.providers.ExoPlayerPlaybackProvider import com.novage.p2pml.providers.ExternalPlaybackProvider @@ -26,8 +26,8 @@ import kotlinx.coroutines.runBlocking /** * `P2PMediaLoader` facilitates peer-to-peer media streaming within an Android application. * - * @param readyCallback Callback invoked when the P2P engine is ready for use - * @param onReadyErrorCallback Callback invoked when an error occurs + * @param onP2PReadyCallback Callback invoked when the P2P engine is ready for use + * @param onP2PReadyErrorCallback Callback invoked when an error occurs * @param coreConfigJson Sets core P2P configurations. See [P2PML Core Config](https://novage.github.io/p2p-media-loader/docs/v2.1.0/types/p2p_media_loader_core.CoreConfig.html) * JSON string with core configurations. Default: empty string (uses default config) * @@ -40,8 +40,8 @@ import kotlinx.coroutines.runBlocking */ @UnstableApi class P2PMediaLoader( - private val readyCallback: P2PReadyCallback, - private val onReadyErrorCallback: OnErrorCallback, + private val onP2PReadyCallback: OnP2PReadyCallback, + private val onP2PReadyErrorCallback: OnP2PReadyErrorCallback, private val coreConfigJson: String = "", private val serverPort: Int = Constants.DEFAULT_SERVER_PORT, private val customJavaScriptInterfaces: List> = emptyList(), @@ -49,13 +49,13 @@ class P2PMediaLoader( ) { // Second constructor for Java compatibility constructor( - readyCallback: P2PReadyCallback, - onReadyErrorCallback: OnErrorCallback, + onP2PReadyCallback: OnP2PReadyCallback, + onP2PReadyErrorCallback: OnP2PReadyErrorCallback, serverPort: Int, coreConfigJson: String, ) : this( - readyCallback, - onReadyErrorCallback, + onP2PReadyCallback, + onP2PReadyErrorCallback, coreConfigJson, serverPort, emptyList(), @@ -139,6 +139,7 @@ class P2PMediaLoader( engineStateManager, customEngineImplementationPath, onServerStarted = { onServerStarted() }, + onServerError = { onP2PReadyErrorCallback.onError(it) }, onManifestChanged = { onManifestChanged() }, ).apply { start(serverPort) } } @@ -220,9 +221,9 @@ class P2PMediaLoader( webViewManager!!.initCoreEngine(coreConfigJson) try { - readyCallback.onReady() + onP2PReadyCallback.onReady() } catch (e: Exception) { - onReadyErrorCallback.onError(e.message ?: "Unknown error") + onP2PReadyErrorCallback.onError(e.message ?: "Unknown error") } } } @@ -235,6 +236,10 @@ class P2PMediaLoader( Utils.getUrl(serverPort, CORE_FILE_URL) } - webViewManager!!.loadWebView(urlPath) + try { + webViewManager!!.loadWebView(urlPath) + } catch (e: Exception) { + onP2PReadyErrorCallback.onError(e.message ?: "Unknown error") + } } } diff --git a/p2pml/src/main/java/com/novage/p2pml/interop/P2PReadyCallback.java b/p2pml/src/main/java/com/novage/p2pml/interop/OnP2PReadyCallback.java similarity index 60% rename from p2pml/src/main/java/com/novage/p2pml/interop/P2PReadyCallback.java rename to p2pml/src/main/java/com/novage/p2pml/interop/OnP2PReadyCallback.java index 58242a0..022d0cf 100644 --- a/p2pml/src/main/java/com/novage/p2pml/interop/P2PReadyCallback.java +++ b/p2pml/src/main/java/com/novage/p2pml/interop/OnP2PReadyCallback.java @@ -1,5 +1,5 @@ package com.novage.p2pml.interop; -public interface P2PReadyCallback { +public interface OnP2PReadyCallback { void onReady(); } diff --git a/p2pml/src/main/java/com/novage/p2pml/interop/OnErrorCallback.java b/p2pml/src/main/java/com/novage/p2pml/interop/OnP2PReadyErrorCallback.java similarity index 61% rename from p2pml/src/main/java/com/novage/p2pml/interop/OnErrorCallback.java rename to p2pml/src/main/java/com/novage/p2pml/interop/OnP2PReadyErrorCallback.java index c3083c5..0a438b4 100644 --- a/p2pml/src/main/java/com/novage/p2pml/interop/OnErrorCallback.java +++ b/p2pml/src/main/java/com/novage/p2pml/interop/OnP2PReadyErrorCallback.java @@ -1,5 +1,5 @@ package com.novage.p2pml.interop; -public interface OnErrorCallback { +public interface OnP2PReadyErrorCallback { void onError(String error); } diff --git a/p2pml/src/main/java/com/novage/p2pml/server/SegmentHandler.kt b/p2pml/src/main/java/com/novage/p2pml/server/SegmentHandler.kt index 3c4f0fe..fb20fd7 100644 --- a/p2pml/src/main/java/com/novage/p2pml/server/SegmentHandler.kt +++ b/p2pml/src/main/java/com/novage/p2pml/server/SegmentHandler.kt @@ -39,11 +39,6 @@ internal class SegmentHandler( val decodedSegmentUrl = Utils.decodeBase64Url(segmentUrlParam) val byteRange = call.request.headers[HttpHeaders.Range] - Log.d( - "SegmentHandler", - "Received segment request for $decodedSegmentUrl", - ) - try { val isCurrentSegment = parser.isCurrentSegment(decodedSegmentUrl) if (p2pEngineStateManager.isEngineDisabled() || !isCurrentSegment) { @@ -58,7 +53,7 @@ internal class SegmentHandler( respondSegment(call, segmentBytes, byteRange != null) } catch (e: SegmentAbortedException) { - Log.e("SegmentHandler", "Segment request aborted: ${e.message}") + Log.w("SegmentHandler", "Segment request aborted: ${e.message}") call.respondText( "Segment aborted", status = HttpStatusCode.RequestTimeout, diff --git a/p2pml/src/main/java/com/novage/p2pml/server/ServerModule.kt b/p2pml/src/main/java/com/novage/p2pml/server/ServerModule.kt index 729845d..6b840aa 100644 --- a/p2pml/src/main/java/com/novage/p2pml/server/ServerModule.kt +++ b/p2pml/src/main/java/com/novage/p2pml/server/ServerModule.kt @@ -23,6 +23,7 @@ internal class ServerModule( private val p2pEngineStateManager: P2PStateManager, private val customEngineImplementationPath: String? = null, private val onServerStarted: () -> Unit, + private val onServerError: (String) -> Unit, private val onManifestChanged: suspend () -> Unit, ) { private var httpClient: OkHttpClient? = null @@ -31,12 +32,15 @@ internal class ServerModule( fun start(port: Int = 8080) { if (server != null) return - server = - embeddedServer(CIO, port) { + try { + server = embeddedServer(CIO, port) { configureCORS(this) configureRouting(this) subscribeToServerStarted(this) }.start(wait = false) + } catch (e: Exception) { + onServerError(e.message ?: "Failed to start server on port $port") + } } private fun stopServer() {