Skip to content

Commit

Permalink
Preload API beta, integration and example (#174)
Browse files Browse the repository at this point in the history
* chore: upgrade IVS player to 1.25.0-rc.2 for prefetch functionality

* feat(js): JS implementation of prefetch, with a wrapper to represent a native source

* feat(android): Android impl of prefetch

* feat(ios): iOS impl of prefetch

* example: simple swipeable video playback example for prefetch scenarios

* example: on unmount, release any remaining sources

* refactor(android): guard against an app forgetting to release a source
  • Loading branch information
cdg-me authored Feb 20, 2024
1 parent 4c1abad commit c153756
Show file tree
Hide file tree
Showing 17 changed files with 483 additions and 20 deletions.
2 changes: 1 addition & 1 deletion amazon-ivs-react-native-player.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ Pod::Spec.new do |s|


s.dependency "React-Core"
s.dependency "AmazonIVSPlayer", "~> 1.23.0"
s.dependency "AmazonIVSPlayer", "~> 1.25.0-rc.2.1"
end
2 changes: 1 addition & 1 deletion android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ AmazonIvs_kotlinVersion=1.6.10
AmazonIvs_compileSdkVersion=31
AmazonIvs_buildToolsVersion=31.0.0
AmazonIvs_targetSdkVersion=31
AmazonIvs_ivsVersion=1.23.0
AmazonIvs_ivsVersion=1.25.0-rc.2
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import android.net.Uri
import android.widget.FrameLayout
import com.amazonaws.ivs.player.*
import android.os.Build
import android.util.Log
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.LifecycleEventListener
import com.facebook.react.bridge.ReactContext
Expand All @@ -31,6 +32,7 @@ class AmazonIvsView(private val context: ThemedReactContext) : FrameLayout(conte
private var finishedLoading: Boolean = false
private var pipEnabled: Boolean = false
private var isInBackground: Boolean = false
private var preloadSourceMap: HashMap<Int, Source> = hashMapOf()


enum class Events(private val mName: String) {
Expand Down Expand Up @@ -320,6 +322,31 @@ class AmazonIvsView(private val context: ThemedReactContext) : FrameLayout(conte
player?.setOrigin(origin)
}

fun preload(id: Int, url: String) {
// Beta API
val mplayer = player as? MediaPlayer
val source = mplayer?.preload(Uri.parse(url))
source?.let {
preloadSourceMap.put(id, source)
}
}

fun loadSource(id: Int) {
// Beta API
val source = preloadSourceMap.get(id)
source?.let {
val mplayer = player as? MediaPlayer
mplayer?.loadSource(source)
}
}

fun releaseSource(id: Int) {
// Beta API
val source = preloadSourceMap.remove(id)
source?.let {
source.release()
}
}

fun onPlayerStateChange(state: Player.State) {
val reactContext = context as ReactContext
Expand Down Expand Up @@ -503,6 +530,12 @@ class AmazonIvsView(private val context: ThemedReactContext) : FrameLayout(conte
}

fun cleanup() {
// Cleanup any remaining sources
for (source in preloadSourceMap.values) {
source.release()
}
preloadSourceMap.clear()

player?.removeListener(playerListener!!)
player?.release()
player = null
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.amazonaws.ivs.reactnative.player

import android.util.Log
import com.facebook.react.bridge.ReadableArray
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.common.MapBuilder
Expand All @@ -9,6 +10,9 @@ import com.facebook.react.uimanager.annotations.ReactProp

class AmazonIvsViewManager : SimpleViewManager<AmazonIvsView>() {
private enum class Commands {
PRELOAD,
LOAD_SOURCE,
RELEASE_SOURCE,
PLAY,
PAUSE,
SEEK_TO,
Expand All @@ -27,22 +31,41 @@ class AmazonIvsViewManager : SimpleViewManager<AmazonIvsView>() {
}

override fun getCommandsMap(): Map<String, Int>? {
return MapBuilder.of(
"play",
Commands.PLAY.ordinal,
"pause",
Commands.PAUSE.ordinal,
"setOrigin",
Commands.SET_ORIGIN.ordinal,
"seekTo",
Commands.SEEK_TO.ordinal,
"togglePip",
Commands.TOGGLE_PIP.ordinal
return mapOf(
"preload" to Commands.PRELOAD.ordinal,
"loadSource" to Commands.LOAD_SOURCE.ordinal,
"releaseSource" to Commands.RELEASE_SOURCE.ordinal,
"play" to Commands.PLAY.ordinal,
"pause" to Commands.PAUSE.ordinal,
"setOrigin" to Commands.SET_ORIGIN.ordinal,
"seekTo" to Commands.SEEK_TO.ordinal,
"togglePip" to Commands.TOGGLE_PIP.ordinal
)
}

override fun receiveCommand(view: AmazonIvsView, commandType: Int, args: ReadableArray?) {
when (commandType) {
Commands.PRELOAD.ordinal -> {
val id = args?.getInt(0)
val url = args?.getString(1)
id?.let {
url?.let {
view.preload(id, url)
}
}
}
Commands.LOAD_SOURCE.ordinal -> {
val id = args?.getInt(0)
id?.let {
view.loadSource(id)
}
}
Commands.RELEASE_SOURCE.ordinal -> {
val id = args?.getInt(0)
id?.let {
view.releaseSource(id)
}
}
Commands.PLAY.ordinal -> view.play()
Commands.PAUSE.ordinal -> view.pause()
Commands.TOGGLE_PIP.ordinal -> view.togglePip()
Expand Down
13 changes: 12 additions & 1 deletion example/android/.project
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>android</name>
<name>AmazonIvsExample</name>
<comment>Project android created by Buildship.</comment>
<projects>
</projects>
Expand All @@ -14,4 +14,15 @@
<natures>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
<filteredResources>
<filter>
<id>1701901663543</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription>
10 changes: 5 additions & 5 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
PODS:
- amazon-ivs-react-native-player (1.4.1):
- AmazonIVSPlayer (~> 1.23.0)
- AmazonIVSPlayer (~> 1.25.0-rc.2.1)
- React-Core
- AmazonIVSPlayer (1.23.0)
- AmazonIVSPlayer (1.25.0-rc.2.1)
- boost (1.76.0)
- CocoaAsyncSocket (7.6.5)
- DoubleConversion (1.1.6)
Expand Down Expand Up @@ -579,8 +579,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
amazon-ivs-react-native-player: d61c43140bd2a006f6181c3d18fbba3e24f388b1
AmazonIVSPlayer: 056aa543826328b578f51d5f3a1ac47b227d813d
amazon-ivs-react-native-player: 8d77be2a79382c8a23bf0650fff90bf2f1597600
AmazonIVSPlayer: eac627800d289abd3d004bc34223137047ec8b5e
boost: a7c83b31436843459a1961bfd74b96033dc77234
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
Expand Down Expand Up @@ -640,4 +640,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 10b965f81e7d51bcd1f3d840c000ea2ebdaf2ec6

COCOAPODS: 1.11.3
COCOAPODS: 1.14.3
6 changes: 6 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import PlaygroundExample from './screens/PlaygroundExample';
import Home from './screens/Home';
import SimpleExample from './screens/SimpleExample';
import AdvancedExample from './screens/AdvancedExample';
import SwipeableExample from './screens/SwipeableExample';
import { TestPlan } from './screens/TestPlan';

export const theme = {
Expand All @@ -30,6 +31,7 @@ export type RootStackParamList = {
TestPlan: undefined;
SimpleExample: undefined;
AdvancedExample: undefined;
SwipeableExample: undefined;
PlaygroundExample: undefined;
};

Expand Down Expand Up @@ -64,6 +66,10 @@ export default function App() {
<Stack.Screen name="TestPlan" component={TestPlan} />
<Stack.Screen name="SimpleExample" component={SimpleExample} />
<Stack.Screen name="AdvancedExample" component={AdvancedExample} />
<Stack.Screen
name="SwipeableExample"
component={SwipeableExample}
/>
<Stack.Screen
name="PlaygroundExample"
component={PlaygroundExample}
Expand Down
14 changes: 14 additions & 0 deletions example/src/screens/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ function Home() {
</Paragraph>
</Card.Content>
</Card>
<Card
testID="Swipeable"
style={styles.card}
onPress={() => {
navigate('SwipeableExample');
}}
>
<Card.Title title="Swipeable" />
<Card.Content>
<Paragraph>
A simple implementation of a swipeable video flow.
</Paragraph>
</Card.Content>
</Card>
<Card
testID="Playground"
style={styles.card}
Expand Down
Loading

0 comments on commit c153756

Please sign in to comment.