-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: initial android implemenation with ExoPlayer
- Loading branch information
Arnaud de Mouhy
committed
Sep 22, 2020
1 parent
1f82b7c
commit 32b4d25
Showing
11 changed files
with
478 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="com.reactnativeradioplayer"> | ||
|
||
<uses-permission android:name="android.permission.WAKE_LOCK" /> | ||
</manifest> |
116 changes: 104 additions & 12 deletions
116
android/src/main/java/com/reactnativeradioplayer/RadioPlayerModule.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,24 +1,116 @@ | ||
package com.reactnativeradioplayer | ||
|
||
import com.facebook.react.bridge.ReactApplicationContext | ||
import com.facebook.react.bridge.ReactContextBaseJavaModule | ||
import com.facebook.react.bridge.ReactMethod | ||
import com.facebook.react.bridge.Promise | ||
import android.util.Log | ||
import com.facebook.react.bridge.* | ||
import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter | ||
import com.google.android.exoplayer2.C.WAKE_MODE_NETWORK | ||
import com.google.android.exoplayer2.MediaItem | ||
import com.google.android.exoplayer2.Player | ||
import com.google.android.exoplayer2.SimpleExoPlayer | ||
import com.google.android.exoplayer2.metadata.Metadata | ||
import com.google.android.exoplayer2.metadata.MetadataOutput | ||
import com.google.android.exoplayer2.metadata.icy.IcyInfo | ||
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector | ||
import com.google.android.exoplayer2.util.EventLogger | ||
|
||
class RadioPlayerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) { | ||
|
||
class RadioPlayerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), Player.EventListener, MetadataOutput { | ||
|
||
private val context = reactContext | ||
private var player: SimpleExoPlayer = SimpleExoPlayer.Builder(reactContext).build() | ||
|
||
override fun getName(): String { | ||
return "RadioPlayer" | ||
} | ||
|
||
// Example method | ||
// See https://facebook.github.io/react-native/docs/native-modules-android | ||
init { | ||
UiThreadUtil.runOnUiThread { | ||
player.addAnalyticsListener(EventLogger(DefaultTrackSelector(this.context))) | ||
player.addMetadataOutput(this) | ||
player.setThrowsWhenUsingWrongThread(true) | ||
player.setWakeMode(WAKE_MODE_NETWORK) | ||
player.addListener(this) | ||
} | ||
} | ||
|
||
@ReactMethod | ||
fun multiply(a: Int, b: Int, promise: Promise) { | ||
|
||
promise.resolve(a * b) | ||
|
||
fun radioURL(uri: String) { | ||
UiThreadUtil.runOnUiThread { | ||
val item: MediaItem = MediaItem.fromUri(uri) | ||
player.setMediaItem(item) | ||
player.prepare() | ||
player.play() | ||
//play() | ||
} | ||
} | ||
|
||
|
||
@ReactMethod | ||
fun play() { | ||
UiThreadUtil.runOnUiThread { | ||
if (player.isPlaying) { | ||
player.stop() | ||
} | ||
player.prepare() | ||
player.play() | ||
} | ||
} | ||
|
||
@ReactMethod | ||
fun stop() { | ||
UiThreadUtil.runOnUiThread { player.stop() } | ||
} | ||
|
||
override fun onPlaybackStateChanged(state: Int) { | ||
var stateString = "unknown" | ||
var playbackStateString = "unknown" | ||
when (state) { | ||
Player.STATE_IDLE, Player.STATE_ENDED -> { | ||
stateString = "loadingFinished" | ||
playbackStateString = "stopped" | ||
} | ||
Player.STATE_BUFFERING -> { | ||
stateString = "loading" | ||
playbackStateString = "paused" | ||
} | ||
Player.STATE_READY -> { | ||
stateString = "loadingFinished" | ||
playbackStateString = "playing" | ||
} | ||
} | ||
val stateMap = WritableNativeMap() | ||
stateMap.putString("state", stateString) | ||
sendEvent(this.context, "StateDidChange", stateMap) | ||
|
||
val playbackStateMap = WritableNativeMap() | ||
playbackStateMap.putString("playbackState", playbackStateString) | ||
sendEvent(this.context, "PlaybackStateDidChange", playbackStateMap) | ||
} | ||
|
||
private fun sendEvent(reactContext: ReactContext, | ||
eventName: String, | ||
params: NativeMap) { | ||
reactContext | ||
.getJSModule(RCTDeviceEventEmitter::class.java) | ||
.emit(eventName, params) | ||
} | ||
|
||
override fun onMetadata(metadata: Metadata) { | ||
Log.i("RadioPlayerMetadata", metadata.toString()) | ||
var artistName = "Unknown" | ||
var trackName = "Unknown" | ||
for (i in 1..metadata.length()) { | ||
val entry: Metadata.Entry = metadata.get(i-1) | ||
if (entry is IcyInfo) { | ||
if (entry.title != null) { | ||
val parts: List<String> = entry.title!!.split(" - ") | ||
artistName = parts[0] | ||
trackName = parts[1] | ||
} | ||
} | ||
} | ||
val metadataMap = WritableNativeMap() | ||
metadataMap.putString("artistName", artistName) | ||
metadataMap.putString("trackName", trackName) | ||
sendEvent(this.context, "MetadataDidChange", metadataMap) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<module external.linked.project.id="RadioPlayerExample" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4"> | ||
<component name="FacetManager"> | ||
<facet type="java-gradle" name="Java-Gradle"> | ||
<configuration> | ||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" /> | ||
<option name="BUILDABLE" value="false" /> | ||
</configuration> | ||
</facet> | ||
</component> | ||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true"> | ||
<exclude-output /> | ||
<content url="file://$MODULE_DIR$"> | ||
<excludeFolder url="file://$MODULE_DIR$/.gradle" /> | ||
</content> | ||
<orderEntry type="inheritedJdk" /> | ||
<orderEntry type="sourceFolder" forTests="false" /> | ||
</component> | ||
</module> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4"> | ||
<component name="FacetManager"> | ||
<facet type="android-gradle" name="Android-Gradle"> | ||
<configuration> | ||
<option name="GRADLE_PROJECT_PATH" value=":app" /> | ||
<option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" value="3.5.2" /> | ||
<option name="LAST_KNOWN_AGP_VERSION" value="3.5.2" /> | ||
</configuration> | ||
</facet> | ||
<facet type="android" name="Android"> | ||
<configuration> | ||
<option name="SELECTED_BUILD_VARIANT" value="debug" /> | ||
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" /> | ||
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" /> | ||
<afterSyncTasks> | ||
<task>generateDebugSources</task> | ||
</afterSyncTasks> | ||
<option name="ALLOW_USER_CONFIGURATION" value="false" /> | ||
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" /> | ||
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" /> | ||
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res;file://$MODULE_DIR$/build/generated/res/resValues/debug" /> | ||
<option name="TEST_RES_FOLDERS_RELATIVE_PATH" value="" /> | ||
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" /> | ||
</configuration> | ||
</facet> | ||
</component> | ||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> | ||
<output url="file://$MODULE_DIR$/build/intermediates/javac/debug/classes" /> | ||
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/classes" /> | ||
<exclude-output /> | ||
<content url="file://$MODULE_DIR$"> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/compileDebugAidl/out" isTestSource="false" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debug/compileDebugRenderscript/out" isTestSource="false" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/react/debug" type="java-resource" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debugAndroidTest/out" isTestSource="true" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debugAndroidTest/compileDebugAndroidTestAidl/out" isTestSource="true" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debugAndroidTest/compileDebugAndroidTestRenderscript/out" isTestSource="true" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debugUnitTest/out" isTestSource="true" generated="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/resources" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/build/generated/rncli/src/main/java" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" /> | ||
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" /> | ||
<excludeFolder url="file://$MODULE_DIR$/build" /> | ||
</content> | ||
<orderEntry type="jdk" jdkName="Android API 28 Platform" jdkType="Android SDK" /> | ||
<orderEntry type="sourceFolder" forTests="false" /> | ||
<orderEntry type="library" scope="TEST" name="Gradle: androidx.multidex:multidex-instrumentation:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.soloader:nativeloader:0.8.2@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.infer.annotation:infer-annotation:0.11.2@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.google.code.findbugs:jsr305:3.0.2@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.collection:collection:1.1.0@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.arch.core:core-common:2.1.0@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.lifecycle:lifecycle-common:2.1.0@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.annotation:annotation:1.1.0@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.squareup.okhttp3:okhttp-urlconnection:3.12.1@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.squareup.okhttp3:okhttp:3.14.1@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.squareup.okio:okio:1.17.2@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.yoga:proguard-annotations:1.14.1@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: javax.inject:javax.inject:1@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.fbjni:fbjni-java-only:0.0.3@jar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.multidex:multidex:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.flipper:flipper:0.33.1@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.react:react-native:0.62.2@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.soloader:soloader:0.8.2@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.soloader:annotation:0.8.2@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.appcompat:appcompat:1.1.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.swiperefreshlayout:swiperefreshlayout:1.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.fragment:fragment:1.1.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.appcompat:appcompat-resources:1.1.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.drawerlayout:drawerlayout:1.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.viewpager:viewpager:1.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.loader:loader:1.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.activity:activity:1.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.vectordrawable:vectordrawable-animated:1.1.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.vectordrawable:vectordrawable:1.1.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.customview:customview:1.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.core:core:1.1.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.interpolator:interpolator:1.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.cursoradapter:cursoradapter:1.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.versionedparcelable:versionedparcelable:1.1.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.lifecycle:lifecycle-viewmodel:2.1.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.lifecycle:lifecycle-runtime:2.1.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.savedstate:savedstate:1.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.lifecycle:lifecycle-livedata:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.lifecycle:lifecycle-livedata-core:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: androidx.arch.core:core-runtime:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.flipper:flipper-network-plugin:0.33.1@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.fresco:imagepipeline-okhttp3:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.flipper:flipper-fresco-plugin:0.33.1@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.fresco:fresco:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.fresco:fbcore:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.fresco:drawee:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.fresco:imagepipeline:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.fresco:imagepipeline-base:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.fresco:nativeimagefilters:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: com.facebook.fresco:nativeimagetranscoder:2.0.0@aar" level="project" /> | ||
<orderEntry type="library" name="Gradle: org.webkit:android-jsc:r245459@aar" level="project" /> | ||
<orderEntry type="module" module-name="reactnativeradioplayer" /> | ||
</component> | ||
</module> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.