Skip to content

Commit a7488ef

Browse files
committed
feat(android): add media preload support
1 parent 25ecb97 commit a7488ef

File tree

5 files changed

+100
-5
lines changed

5 files changed

+100
-5
lines changed

packages/canvas-media/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nativescript/canvas-media",
3-
"version": "0.8.0",
3+
"version": "0.9.0",
44
"description": "Canvas media",
55
"main": "index",
66
"typings": "index.d.ts",
Binary file not shown.

packages/canvas-media/platforms/android/include.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
android {
2+
compileOptions {
3+
sourceCompatibility JavaVersion.VERSION_1_8
4+
targetCompatibility JavaVersion.VERSION_1_8
5+
}
6+
}
7+
18
dependencies {
29
implementation 'com.google.android.exoplayer:exoplayer:2.13.2'
310
implementation 'com.google.android.exoplayer:exoplayer-ui:2.13.2'
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package org.nativescript.canvas_media;
2+
import android.content.Context;
3+
import android.net.Uri;
4+
5+
import com.google.android.exoplayer2.database.ExoDatabaseProvider;
6+
import com.google.android.exoplayer2.upstream.DataSource;
7+
import com.google.android.exoplayer2.upstream.DataSpec;
8+
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
9+
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
10+
import com.google.android.exoplayer2.upstream.cache.CacheWriter;
11+
import com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor;
12+
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
13+
import com.google.android.exoplayer2.util.Util;
14+
15+
import java.io.File;
16+
import java.io.IOException;
17+
import java.util.concurrent.Executor;
18+
import java.util.concurrent.Executors;
19+
20+
21+
public class Utils {
22+
private static Executor executor = Executors.newCachedThreadPool();
23+
private static SimpleCache cache;
24+
private static LeastRecentlyUsedCacheEvictor leastRecentlyUsedCacheEvictor;
25+
private static ExoDatabaseProvider exoDatabaseProvider;
26+
private static long exoPlayerCacheSize = 100 * 1024 * 1024;
27+
private static java.io.File cacheDir;
28+
private static boolean didInit;
29+
private static String packageName;
30+
31+
public static void init(Context context, String cacheDir) {
32+
init(context, cacheDir, exoPlayerCacheSize);
33+
}
34+
35+
public static void init(Context context, String cacheDir, long exoPlayerCacheSize) {
36+
if (!didInit) {
37+
Utils.packageName = context.getPackageName();
38+
Utils.cacheDir = new File(cacheDir);
39+
Utils.exoPlayerCacheSize = exoPlayerCacheSize;
40+
if (!Utils.cacheDir.exists()) {
41+
Utils.cacheDir.mkdirs();
42+
}
43+
44+
leastRecentlyUsedCacheEvictor = new com.google.android.exoplayer2.upstream.cache.LeastRecentlyUsedCacheEvictor(exoPlayerCacheSize);
45+
46+
exoDatabaseProvider = new com.google.android.exoplayer2.database.ExoDatabaseProvider(context);
47+
cache = new com.google.android.exoplayer2.upstream.cache.SimpleCache(Utils.cacheDir, leastRecentlyUsedCacheEvictor, exoDatabaseProvider);
48+
didInit = true;
49+
}
50+
}
51+
52+
public static void cacheUrl(final Context context, final String url) {
53+
executor.execute(new Runnable() {
54+
@Override
55+
public void run() {
56+
Uri videoUri = Uri.parse(url);
57+
DataSpec dataSpec = new DataSpec(videoUri);
58+
59+
DataSource dataSource =
60+
new DefaultDataSourceFactory(
61+
context,
62+
Util.getUserAgent(context, packageName)).createDataSource();
63+
64+
try {
65+
new CacheWriter(
66+
new CacheDataSource(cache, dataSource), dataSpec, true, null, null
67+
).cache();
68+
} catch (IOException ignored) {
69+
}
70+
}
71+
});
72+
}
73+
}

packages/canvas-media/video/index.android.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export class Video extends VideoBase {
2727
#autoplay: boolean;
2828
#loop: boolean;
2929
#textureView: android.view.TextureView;
30+
3031
_isCustom: boolean = false;
3132
_playing: boolean = false;
3233
_timer: any;
@@ -39,13 +40,22 @@ export class Video extends VideoBase {
3940
_readyState: number = 0;
4041
_videoWidth = 0;
4142
_videoHeight = 0;
43+
private static _didInit = false;
4244
constructor() {
4345
super();
4446
try {
4547
java.lang.System.loadLibrary('canvasnative');
4648
} catch (ex) {}
49+
50+
4751
//@ts-ignore
4852
const activity: androidx.appcompat.app.AppCompatActivity = Application.android.foregroundActivity || Application.android.startActivity;
53+
54+
if(!Video._didInit){
55+
// @ts-ignore
56+
org.nativescript.canvas_media.Utils.init(activity, path.join(knownFolders.documents().path, 'MEDIA_PLAYER_CACHE'));
57+
}
58+
4959
const builder = new com.google.android.exoplayer2.SimpleExoPlayer.Builder(activity);
5060
this.#player = builder.build();
5161
const ref = new WeakRef(this);
@@ -93,7 +103,7 @@ export class Video extends VideoBase {
93103
//console.log('PlayerError', error);
94104
},
95105
onPlayerStateChanged: function (playWhenReady, playbackState) {
96-
//console.log('onPlayerStateChanged', Date.now());
106+
// console.log('onPlayerStateChanged', Date.now(), playbackState , STATE_BUFFERING);
97107
// if (playbackState === STATE_READY) {
98108
// playerReady = true;
99109
// } else if (playbackState === STATE_ENDED) {
@@ -166,6 +176,11 @@ export class Video extends VideoBase {
166176
if (typeof value === 'string' && value.startsWith('~/')) {
167177
value = path.join(knownFolders.currentApp().path, value.replace('~', ''));
168178
}
179+
if(typeof value === 'string' && value.startsWith('http')){
180+
// @ts-ignore
181+
org.nativescript.canvas_media.Utils.cacheUrl(Application.android.foregroundActivity || Application.android.startActivity, value);
182+
}
183+
169184
this.#player.addMediaItem(com.google.android.exoplayer2.MediaItem.fromUri(android.net.Uri.parse(value)));
170185
this.#player.prepare();
171186
if (this.#autoplay) {
@@ -184,15 +199,15 @@ export class Video extends VideoBase {
184199
const st = surfaceView.getSurfaceTexture();
185200
if (st) {
186201
// @ts-ignore
187-
this._render = com.github.triniwiz.canvas.Utils.createRenderAndAttachToGLContext(context, st);
202+
this._render = org.nativescript.canvas.Utils.createRenderAndAttachToGLContext(context, st);
188203
this._st = st;
189204
}
190205
}
191206
}
192207

193208
if (!this._st) {
194209
// @ts-ignore
195-
const result = com.github.triniwiz.canvas.Utils.createSurfaceTexture(context);
210+
const result = org.nativescript.canvas.Utils.createSurfaceTexture(context);
196211
this._st = result[0];
197212
const ref = new WeakRef(this);
198213
this._frameListener = new android.graphics.SurfaceTexture.OnFrameAvailableListener({
@@ -217,7 +232,7 @@ export class Video extends VideoBase {
217232
return;
218233
}
219234
// @ts-ignore
220-
com.github.triniwiz.canvas.Utils.updateTexImage(context, this._st, this._render, this._videoWidth, this._videoHeight, arguments[4], arguments[5]);
235+
org.nativescript.canvas.Utils.updateTexImage(context, this._st, this._render, this._videoWidth, this._videoHeight, arguments[4], arguments[5]);
221236
this._hasFrame = false;
222237
}
223238
}

0 commit comments

Comments
 (0)