Как использовать RajawaliVR или Rajawali для воспроизведения видео 360

Мне трудно понять, как использовать Rajawali для воспроизведения видео 360. Чтобы добиться этого, я перепробовал каждое решение, которое смог найти в Интернете, но потерпел неудачу.

Во-первых, я использовал RajawaliCardboard, и позволил MainActivity расширяться от CardboardActivity, В то же время, в MyRenderer класс, я позволил этому классу расширяться от RajawaliCardboardRenderer учебный класс. В MyRenderer класс, я переопределил initScene() функция:

protected void initScene() {
    StreamingTexture mTexture = null;
    if (externalMemoryAvailable())
    {
        mVideoPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/testVideo.mp4";
        try{
            mPlayer = new MediaPlayer();
            mPlayer.setDataSource(mVideoPath);
        }catch(IllegalArgumentException e){
        e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        try {
            mPlayer.prepare();
        } catch (IOException t) {
            t.printStackTrace();
        }
        mTexture = new StreamingTexture("video", mPlayer);
    }
    Sphere sphere = createPhotoSphereWithTexture(mTexture);
    getCurrentScene().addChild(sphere);
    getCurrentCamera().setPosition(Vector3.ZERO);
    getCurrentCamera().setFieldOfView(75);
}

private  Sphere createPhotoSphereWithTexture(ATexture texture) {
    Material material = new Material();
    material.setColor(0);
    try {
        material.addTexture(texture);
    } catch (ATexture.TextureException e) {
        throw new RuntimeException(e);
    }
    Sphere sphere = new Sphere(50, 64, 32);
    sphere.setScaleX(-1);
    sphere.setMaterial(material);
    return sphere;
}

Программа может работать без ошибок, но экран черный и без изображения.
Я хочу спросить, что я должен сделать, чтобы улучшить свою программу, и почему я должен сделать, чтобы воспроизвести видео с помощью Rajawali. Кто может мне помочь?

3 ответа

Решение

Мне удалось сыграть видео с Раджавали.

public class VideoRenderer extends RajawaliCardboardRenderer {

    Context mContext;

    private MediaPlayer mMediaPlayer;
    private StreamingTexture mVideoTexture;

    public VideoRenderer(Context context) {
        super(context);
        mContext = context;
    }

    @Override
    protected void initScene() {

        mMediaPlayer = MediaPlayer.create(getContext(),
                R.raw.video);
        mMediaPlayer.setLooping(true);

        mVideoTexture = new StreamingTexture("sintelTrailer", mMediaPlayer);
        Material material = new Material();
        material.setColorInfluence(0);
        try {
            material.addTexture(mVideoTexture);
        } catch (ATexture.TextureException e) {
            e.printStackTrace();
        }

        Sphere sphere = new Sphere(50, 64, 32);
        sphere.setScaleX(-1);
        sphere.setMaterial(material);

        getCurrentScene().addChild(sphere);

        getCurrentCamera().setPosition(Vector3.ZERO);

        getCurrentCamera().setFieldOfView(75);

        mMediaPlayer.start();

    }

    @Override
    protected void onRender(long ellapsedRealtime, double deltaTime) {
        super.onRender(ellapsedRealtime, deltaTime);
        mVideoTexture.update();
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mMediaPlayer != null)
            mMediaPlayer.pause();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (mMediaPlayer != null)
            mMediaPlayer.start();
    }

    @Override
    public void onRenderSurfaceDestroyed(SurfaceTexture surfaceTexture) {
        super.onRenderSurfaceDestroyed(surfaceTexture);
        mMediaPlayer.stop();
        mMediaPlayer.release();
    }
    public void nextVideo(String nextVideoPath){
        try{
            mMediaPlayer.stop();
            mMediaPlayer.reset();

            mMediaPlayer.setDataSource(nextVideoPath);
            mMediaPlayer.prepare();
            mMediaPlayer.start();

      }catch (Exception e){
        e.printStackTrace();
      }
    }
}

Я думаю, что ваша главная ошибка заключается в том, чтобы позвонить MediaPlayer.prepare() в медиаплеере а не MediaPlayer.prepareAsync()
Вы должны учитывать различные состояния, через которые проходит MediaPlayer при воспроизведении видео. Здесь у вас есть ссылка на диаграмму состояний. Вы должны только позвонить MediaPlayer.start() как только видеоплеер закончил готовить все, чтобы видео начало воспроизводиться.
Я работаю над тем же (видеоплеер для 360 видео) с Rajawali, и до сих пор мне удалось воспроизвести их в обычном режиме Gyroscope и Touch, но я нахожу множество проблем, чтобы заставить его работать с Google Картонная интеграция, поэтому я сейчас пытаюсь сделать свой собственный рендер "sideBySide".

Если моих комментариев недостаточно, здесь у вас есть пример кода, который я сейчас использую, чтобы воспроизвести видео в виде потоковой текстуры в Сфере. Это часть переопределенного метода initScene() на класс, который расширяется RajawaliRenderer

//create a 100 segment sphere
    earthSphere = new Sphere(1, 100, 100);
    //try to set the mediaPLayer data source
    mMediaPlayer = new MediaPlayer();
    try{
        mMediaPlayer.setDataSource(context, Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.pyrex));
    }catch(IOException ex){
        Log.e("ERROR","couldn attach data source to the media player");
    }
    mMediaPlayer.setLooping(true);  //enable video looping
    video = new StreamingTexture("pyrex",mMediaPlayer); //create video texture
    mMediaPlayer.prepareAsync();    //prepare the player (asynchronous)
    mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mp) {
            mp.start(); //start the player only when it is prepared
        }
    });
    //add textture to a new material
    Material material = new Material ();
    material.setColorInfluence(0f);
    try{
        material.addTexture(video);
    }catch(ATexture.TextureException ex){
        Log.e("ERROR","texture error when adding video to material");
    }
    //set the material to the sphere
    earthSphere.setMaterial(material);
    earthSphere.setPosition(0, 0, 0);
    //add the sphere to the rendering scene
    getCurrentScene().addChild(earthSphere);

Поскольку вы хотите воспроизвести видео 360, вам нужен трекер ориентации. Вот пример для картонной деятельности.

public class CardboardRendererExample extends Renderer implements CardboardView.StereoRenderer {
public static final int FIELD_OF_VIEW = 90;
public static final float PLANE_WIDTH = 64.0f;
public static final float PLANE_HEIGHT = 36.0f;
public static final float PLANE_DISTANCE = -64.0f;

private final MediaPlayer mMediaPlayer;
protected StreamingTexture mStreamingTexture;

protected Quaternion mOrientation = Quaternion.getIdentity();
protected Quaternion mEyeOrientation = Quaternion.getIdentity();

protected float[] mHeadView = new float[16];
private Matrix4 mEyeMatrix = new Matrix4();
private Vector3 mEyePosition = new Vector3();
private Matrix4 mHeadViewMatrix4 = new Matrix4();

public CardboardRendererExample(Context context, MediaPlayer mediaPlayer) {
    super(context);

    mMediaPlayer = mediaPlayer;
}

@Override
protected void initScene() {
    getCurrentCamera().setPosition(Vector3.ZERO);
    getCurrentCamera().setFieldOfView(FIELD_OF_VIEW);

    mStreamingTexture = new StreamingTexture("give_it_some_name", mMediaPlayer);
    mStreamingTexture.shouldRecycle(true);
    setSceneCachingEnabled(true);

    final Plane projectionScreen = new Plane(PLANE_WIDTH, PLANE_HEIGHT, 64, 64);
    final Material material = new Material();
    material.setColor(0);
    material.setColorInfluence(0f);
    try {
        material.addTexture(mStreamingTexture);
    } catch (ATexture.TextureException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }

    projectionScreen.setDoubleSided(true);
    projectionScreen.setMaterial(material);
    projectionScreen.setTransparent(true);
    projectionScreen.setPosition(0, 0, PLANE_DISTANCE);
    getCurrentScene().addChild(projectionScreen);

    getCurrentScene().addChild(projectionScreen);
}

@Override
public void onNewFrame(HeadTransform headTransform) {
    headTransform.getHeadView(mHeadView, 0);

    mHeadViewMatrix4.setAll(mHeadView).inverse();
    mOrientation.fromMatrix(mHeadViewMatrix4);
}

@Override
public void onDrawEye(Eye eye) {
    getCurrentCamera().updatePerspective(
            eye.getFov().getLeft(),
            eye.getFov().getRight(),
            eye.getFov().getBottom(),
            eye.getFov().getTop());

    mEyeMatrix.setAll(eye.getEyeView());
    mEyeOrientation.fromMatrix(mEyeMatrix);
    getCurrentCamera().setOrientation(mEyeOrientation);
    mEyePosition = mEyeMatrix.getTranslation(mEyePosition).inverse();
    getCurrentCamera().setPosition(mEyePosition);

    super.onRenderFrame(null);
}

@Override
public void onFinishFrame(Viewport viewport) {
}

@Override
public void onSurfaceChanged(int width, int height) {
    super.onRenderSurfaceSizeChanged(null, width, height);
}

@Override
public void onSurfaceCreated(EGLConfig eglConfig) {
    super.onRenderSurfaceCreated(eglConfig, null, -1, -1);
}

@Override
public void onRenderSurfaceCreated(EGLConfig config, GL10 gl, int width, int height) {
    super.onRenderSurfaceCreated(config, gl, width, height);
}

@Override
public void onRendererShutdown() {
}

@Override
protected void onRender(long elapsedRealTime, double deltaTime) {
    super.onRender(elapsedRealTime, deltaTime);
    if (mStreamingTexture != null) {
        mStreamingTexture.update();
    }
}

@Override
public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) {
}

@Override
public void onTouchEvent(MotionEvent event) {
}

}

В качестве альтернативы вы можете реализовать свой трекер на основе (например)

com.google.vrtoolkit.cardboard.sensors.HeadTracker

Конечно, вы можете избавиться от всех этих полей, но они должны облегчить жизнь GC.

Другие вопросы по тегам