@bezlepkin/nativescript-ar
Version:
NativeScript Augmented Reality plugin. ARKit on iOS and (with the help of Sceneform) ARCore on Android.
160 lines (159 loc) • 7.55 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ARVideo = void 0;
const core_1 = require("@nativescript/core");
const arcommon_1 = require("./arcommon");
let pixelsPerMeter = 500;
const alignCenter = (node) => {
node.setLocalPosition(new com.google.ar.sceneform.math.Vector3(0, -node.getLocalScale().y / 2, 0));
};
const alignBottom = (node) => {
node.setLocalPosition(new com.google.ar.sceneform.math.Vector3(0, 0, 0));
};
class ARVideo extends arcommon_1.ARCommonNode {
isPlaying() {
return this.mediaPlayer && this.mediaPlayer.isPlaying();
}
play() {
if (this.mediaPlayer) {
this.mediaPlayer.start();
}
}
pause() {
if (this.mediaPlayer) {
this.mediaPlayer.pause();
}
}
static create(options, fragment) {
return new Promise(async (resolve, reject) => {
const node = arcommon_1.ARCommonNode.createNode(options, fragment);
const videoNode = arcommon_1.ARCommonNode.createNode(options, fragment);
videoNode.setParent(node);
const size = new com.google.ar.sceneform.math.Vector3(options.dimensions instanceof Object ? options.dimensions.x : options.dimensions || 0.96, options.dimensions instanceof Object ? options.dimensions.y : options.dimensions || 0.56, 1);
videoNode.setLocalScale(size);
alignCenter(videoNode);
const texture = new com.google.ar.sceneform.rendering.ExternalTexture();
const mediaPlayer = ARVideo.getPlayer(options);
mediaPlayer.setSurface(texture.getSurface());
mediaPlayer.setVideoScalingMode(android.media.MediaPlayer.VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
const loop = options.loop !== false;
if (loop) {
mediaPlayer.setLooping(true);
}
let videoMat;
ARVideo.getModel().then(renderable => {
videoMat = renderable.getMaterial();
com.google.ar.sceneform.rendering.MaterialFactory.makeOpaqueWithColor(core_1.Utils.ad.getApplicationContext(), new com.google.ar.sceneform.rendering.Color(android.graphics.Color.MAGENTA))
.thenAccept(new java.util.function.Consumer({
accept: material => {
renderable.setMaterial(material);
videoNode.setRenderable(renderable);
const arVideo = new ARVideo(options, node);
arVideo.mediaPlayer = mediaPlayer;
resolve(arVideo);
}
}))
.exceptionally(new java.util.function.Function({
apply: error => reject(error)
}));
videoMat.setExternalTexture("videoTexture", texture);
videoMat.setBoolean("disableChromaKey", true);
mediaPlayer.setOnPreparedListener(new android.media.MediaPlayer.OnPreparedListener({
onPrepared: (mp) => {
const width = mp.getVideoWidth();
const height = mp.getVideoHeight();
if (!options.dimensions) {
videoNode.setLocalScale(new com.google.ar.sceneform.math.Vector3(width / pixelsPerMeter, height / pixelsPerMeter, 1));
}
alignCenter(videoNode);
console.log([height, width]);
mediaPlayer.start();
texture
.getSurfaceTexture()
.setOnFrameAvailableListener(new android.graphics.SurfaceTexture.OnFrameAvailableListener({
onFrameAvailable: (surfaceTexture) => {
console.log('available');
try {
renderable.setMaterial(videoMat);
texture.getSurfaceTexture().setOnFrameAvailableListener(null);
}
catch (e) {
console.error(e);
}
}
}));
}
}));
mediaPlayer.prepareAsync();
}).catch(console.error);
});
}
static getModel() {
return new Promise((resolve, reject) => {
try {
com.google.ar.sceneform.rendering.ModelRenderable.builder()
.setSource(core_1.Utils.ad.getApplicationContext(), android.net.Uri.parse("video_chroma.sfb"))
.build()
.thenAccept(new java.util.function.Consumer({
accept: renderable => {
resolve(renderable);
}
}))
.exceptionally(new java.util.function.Function({
apply: error => {
console.log("g");
reject(error);
}
}));
}
catch (e) {
reject(e);
}
});
}
static getPlayer(options) {
const video = options.video;
const context = core_1.Utils.ad.getApplicationContext();
if (typeof video === "string") {
try {
const mediaPlayer = new android.media.MediaPlayer();
if (video.indexOf("://") >= 0) {
mediaPlayer.setDataSource(context, android.net.Uri.parse(video));
}
else {
mediaPlayer.setDataSource(context.getAssets().openFd(video));
}
mediaPlayer.setOnErrorListener(new android.media.MediaPlayer.OnErrorListener({
onError: (mp, what, extra) => {
console.error("MediaPlayer Error " + what + " with " + video);
([
[android.media.MediaPlayer.MEDIA_ERROR_IO, "MEDIA_ERROR_IO"],
[android.media.MediaPlayer.MEDIA_ERROR_MALFORMED, "MEDIA_ERROR_MALFORMED"],
[android.media.MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK, "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK"],
[android.media.MediaPlayer.MEDIA_ERROR_SERVER_DIED, "MEDIA_ERROR_SERVER_DIED"],
[android.media.MediaPlayer.MEDIA_ERROR_TIMED_OUT, "MEDIA_ERROR_TIMED_OUT"],
[android.media.MediaPlayer.MEDIA_ERROR_UNKNOWN, "MEDIA_ERROR_UNKNOWN"],
[android.media.MediaPlayer.MEDIA_ERROR_UNSUPPORTED, "MEDIA_ERROR_UNSUPPORTED"]
]).forEach(code => {
if (what === code[0]) {
console.log(code[1]);
}
if (extra === code[0]) {
console.log(code[1]);
}
});
return true;
}
}));
return mediaPlayer;
}
catch (e) {
console.error(video);
console.error(e);
}
}
console.log('throw');
throw 'Error';
}
}
exports.ARVideo = ARVideo;