LoginSignup
3
2

More than 5 years have passed since last update.

UnityでExoPlayerを使ってアンビソニック音声ファイルを再生する

Posted at

UnityでExoPlayerを使ってアンビソニック音声ファイルを再生したかったので、作ってみました。

Androidライブラリを作成

まずAndroid StudioでAndroidライブラリのプロジェクトを作り、以下のようなクラスを作成します。このクラスはExoPlayerのインスタンスを作ったりURIの読み込みをしたりするメソッドを提供します。

import android.content.Context;
import android.net.Uri;

import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.ext.gvr.GvrAudioProcessor;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;

public class UnityExoPlayer {

    private final GvrAudioProcessor audioProcessor = new GvrAudioProcessor();
    private final SimpleExoPlayer player;
    private final ExtractorMediaSource.Factory factory;

    public UnityExoPlayer(Context context) {

        final DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context) {
            @Override
            protected AudioProcessor[] buildAudioProcessors() {
                return new AudioProcessor[]{audioProcessor};
            }
        };

        player = ExoPlayerFactory.newSimpleInstance(renderersFactory, new DefaultTrackSelector());
        factory = new ExtractorMediaSource.Factory(new DefaultDataSourceFactory(context, Util.getUserAgent(context, "UnityExoPlayer")));
    }

    public void prepare(String uri) {
        ExtractorMediaSource mediaSource = factory.createMediaSource(Uri.parse(uri));
        player.prepare(mediaSource);
    }

    public void play() {
        player.setPlayWhenReady(true);
    }

    public void pause() {
        player.setPlayWhenReady(false);
    }

    public void stop() {
        player.stop();
    }

    public void release() {
        player.release();
    }

    public void updateOrientation(float w, float x, float y, float z) {
        audioProcessor.updateOrientation(w, x, y, z);
    }

}

このコードをコンパイルするためには以下のようなbuild.gradleのdependenciesが必要です。

dependencies {
    implementation 'com.google.android.exoplayer:exoplayer-core:2.8.1'
    implementation 'com.google.vr:sdk-audio:1.150.0'
}

そしたらGradleのassembleビルドを動かしてaarファイルを作ります。

キャプチャ.PNG

Unityプロジェクトへaarファイルを入れる

↑で作ったaarには、ExoPlayerとGVR Audioのクラスは含まれていないため、別途aarファイルを持ってきてUnityプロジェクトに入れます。aarは以下のリンク先からダウンロードできます。2018/06/15時点の最新版はそれぞれExoPlayerが2.8.1、GVR Audioは1.150.0です。

Unity側のクラスを作成

次に、↑のJavaクラスをC#から呼び出すためのラッパーを書きます。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class UnityExoPlayer
{

  private AndroidJavaObject javaInstance;

  public UnityExoPlayer()
  {
    using (AndroidJavaClass javaUnityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
    {
      using (var currentActivity = javaUnityPlayer.GetStatic<AndroidJavaObject>("currentActivity"))
      {
        //                                   ↓ここのクラス名はパッケージ名に合わせて書き換える
        javaInstance = new AndroidJavaObject("com.niusounds.unityexoplayer.UnityExoPlayer", currentActivity);
      }
    }
  }

  public void Prepare(string uri)
  {
    javaInstance.Call("prepare", uri);
  }

  public void Play()
  {
    javaInstance.Call("play");
  }

  public void Pause()
  {
    javaInstance.Call("pause");
  }

  public void Stop()
  {
    javaInstance.Call("stop");
  }

  public void SetTexture(int texPtr)
  {
    javaInstance.Call("setTexture", texPtr);
  }

  public void Release()
  {
    javaInstance.Call("release");
  }

  public void UpdateOrientation(float w, float x, float y, float z)
  {
    javaInstance.Call("updateOrientation", w, x, y, z);
  }

}

使う

ここまでできたら、UnityExoPlayerクラスを使うことでExoPlayerを使った空間音響の再生ができるようになります。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ExoPlayerComponent : MonoBehaviour
{
  private UnityExoPlayer player;

  void Awake()
  {
    player = new UnityExoPlayer();
  }

  void Start()
  {
    player.Prepare("/path/to/audio");
    player.Play();
  }

  void Update()
  {
    var orientation = Quaternion.Inverse(Camera.main.transform.rotation);
    player.UpdateOrientation(orientation.w, orientation.x, orientation.y, orientation.z);
  }
}

動画対応について

player.Prepareに動画のURIを渡せば、アンビソニック音声付き動画の音声だけは再生できます。あとはUnityのテクスチャをどうにかしてExoPlayerに渡してUnityシーン中の球の表面に映像を出せればアンビソニック付き360動画の完全なプレイヤーが作れるのですが…どなたか挑戦した方がいたら教えてください。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2