FittsLaw/Assets/GoogleVR/Scripts/Video/GvrVideoPlayerTexture.cs

1018 lines
27 KiB
C#
Raw Permalink Normal View History

2018-10-08 23:54:11 -04:00
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Runtime.InteropServices;
using System;
using System.Collections.Generic;
/// <summary>
/// Plays video using Exoplayer rendering it on the main texture.
/// </summary>
[HelpURL("https://developers.google.com/vr/unity/reference/class/GvrVideoPlayerTexture")]
public class GvrVideoPlayerTexture : MonoBehaviour {
/// <summary>
/// The video player pointer used to uniquely identify the player instance.
/// </summary>
private IntPtr videoPlayerPtr;
/// <summary>
/// The video player event base.
/// </summary>
/// <remarks>This is added to the event id when issues events to
/// the plugin.
/// </remarks>
private int videoPlayerEventBase;
private Texture initialTexture;
private Texture surfaceTexture;
private float[] videoMatrixRaw;
private Matrix4x4 videoMatrix;
private int videoMatrixPropertyId;
private long lastVideoTimestamp;
private bool initialized;
private int texWidth = 1024;
private int texHeight = 1024;
private long lastBufferedPosition;
private float framecount = 0;
private Renderer screen;
/// <summary>
/// The render event function.
/// </summary>
private IntPtr renderEventFunction;
private bool playOnResume;
/// <summary>List of callbacks to invoke when the video is ready.</summary>
private List<Action<int>> onEventCallbacks;
/// <summary>List of callbacks to invoke on exception.</summary>
/// <remarks>The first parameter is the type of exception,
/// the second is the message.
/// </remarks>
private List<Action<string, string>> onExceptionCallbacks;
private readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
// Attach a text component to get some debug status info.
public Text statusText;
/// <summary>
/// Video type.
/// </summary>
public enum VideoType {
Dash = 0,
HLS = 2,
Other = 3
};
public enum VideoResolution {
Lowest = 1,
_720 = 720,
_1080 = 1080,
_2048 = 2048,
Highest = 4096
};
/// <summary>
/// Video player state.
/// </summary>
public enum VideoPlayerState {
Idle = 1,
Preparing = 2,
Buffering = 3,
Ready = 4,
Ended = 5
};
public enum VideoEvents {
VideoReady = 1,
VideoStartPlayback = 2,
VideoFormatChanged = 3,
VideoSurfaceSet = 4,
VideoSizeChanged = 5
};
public enum StereoMode {
NoValue = -1,
Mono = 0,
TopBottom = 1,
LeftRight = 2
}
/// <summary>
/// Plugin render commands.
/// </summary>
/// <remarks>
/// These are added to the eventbase for the specific player object and
/// issued to the plugin.
/// </remarks>
private enum RenderCommand {
None = -1,
InitializePlayer = 0,
UpdateVideo = 1,
RenderMono = 2,
RenderLeftEye = 3,
RenderRightEye = 4,
Shutdown = 5
};
/// <summary>
/// The type of the video.
/// </summary>
public VideoType videoType;
public string videoURL;
public string videoContentID;
public string videoProviderId;
public VideoResolution initialResolution = VideoResolution.Highest;
/// <summary>
/// True for adjusting the aspect ratio of the renderer.
/// </summary>
public bool adjustAspectRatio;
/// <summary>
/// The use secure path for DRM protected video.
/// </summary>
public bool useSecurePath;
public bool VideoReady {
get {
return videoPlayerPtr != IntPtr.Zero && IsVideoReady(videoPlayerPtr);
}
}
public long CurrentPosition {
get {
return videoPlayerPtr != IntPtr.Zero ? GetCurrentPosition(videoPlayerPtr) : 0;
}
set {
// If the position is being set to 0, reset the framecount as well.
// This allows the texture swapping to work correctly at the beginning
// of the stream.
if (value == 0) {
framecount = 0;
}
SetCurrentPosition(videoPlayerPtr, value);
}
}
public long VideoDuration {
get {
return videoPlayerPtr != IntPtr.Zero ? GetDuration(videoPlayerPtr) : 0;
}
}
public long BufferedPosition {
get {
return videoPlayerPtr != IntPtr.Zero ? GetBufferedPosition(videoPlayerPtr) : 0;
}
}
public int BufferedPercentage {
get {
return videoPlayerPtr != IntPtr.Zero ? GetBufferedPercentage(videoPlayerPtr) : 0;
}
}
public bool IsPaused {
get {
return !initialized || videoPlayerPtr == IntPtr.Zero || IsVideoPaused(videoPlayerPtr);
}
}
public VideoPlayerState PlayerState {
get {
return videoPlayerPtr != IntPtr.Zero ? (VideoPlayerState)GetPlayerState(videoPlayerPtr) : VideoPlayerState.Idle;
}
}
public int MaxVolume {
get {
return videoPlayerPtr != IntPtr.Zero ? GetMaxVolume(videoPlayerPtr) : 0;
}
}
public int CurrentVolume {
get {
return videoPlayerPtr != IntPtr.Zero ? GetCurrentVolume(videoPlayerPtr) : 0;
}
set {
SetCurrentVolume(value);
}
}
public StereoMode CurrentStereoMode {
get {
return videoPlayerPtr != IntPtr.Zero ? (StereoMode)GetStereoMode(videoPlayerPtr) : StereoMode.NoValue;
}
}
public bool HasProjection {
get {
return videoPlayerPtr != IntPtr.Zero ? HasProjectionData(videoPlayerPtr) : false;
}
}
public Renderer Screen {
get {
return screen;
}
set {
if (screen == value) {
return;
}
if (screen != null && initialTexture != null) {
screen.sharedMaterial.mainTexture = initialTexture;
}
screen = value;
if (screen != null) {
initialTexture = screen.sharedMaterial.mainTexture;
}
}
}
public Texture CurrentFrameTexture {
get {
return surfaceTexture;
}
}
public int Width {
get {
return texWidth;
}
}
public int Height {
get {
return texHeight;
}
}
public float AspectRatio {
get {
if (texHeight == 0) {
return 0.0f;
}
return (float)texWidth / (float)texHeight;
}
}
/// Create the video player instance and the event base id.
void Awake() {
videoMatrixRaw = new float[16];
videoMatrixPropertyId = Shader.PropertyToID("video_matrix");
// Defaults the Screen to the Renderer component on the same object as this script.
// The Screen can also be set explicitly.
Screen = GetComponent<Renderer>();
CreatePlayer();
}
void CreatePlayer() {
videoPlayerPtr = CreateVideoPlayer();
videoPlayerEventBase = GetVideoPlayerEventBase(videoPlayerPtr);
Debug.Log(" -- " + gameObject.name + " created with base " +
videoPlayerEventBase);
SetOnVideoEventCallback((eventId) => {
Debug.Log("------------- E V E N T " + eventId + " -----------------");
UpdateStatusText();
});
SetOnExceptionCallback((type, msg) => {
Debug.LogError("Exception: " + type + ": " + msg);
});
initialized = false;
}
void OnDisable() {
if (videoPlayerPtr != IntPtr.Zero) {
if (GetPlayerState(videoPlayerPtr) == (int)VideoPlayerState.Ready) {
PauseVideo(videoPlayerPtr);
}
}
}
/// <summary>
/// Sets the display texture.
/// </summary>
/// <param name="texture">Texture to display.
// If null, the initial texture of the renderer is used.</param>
public void SetDisplayTexture(Texture texture) {
if (texture == null) {
texture = initialTexture;
}
if (texture == null) {
return;
}
if (screen != null) {
screen.sharedMaterial.mainTexture = texture;
}
}
public void CleanupVideo() {
Debug.Log("Cleaning Up video!");
if (videoPlayerPtr != IntPtr.Zero) {
DestroyVideoPlayer(videoPlayerPtr);
videoPlayerPtr = IntPtr.Zero;
}
if (surfaceTexture != null) {
Destroy(surfaceTexture);
surfaceTexture = null;
}
if (screen != null) {
screen.sharedMaterial.mainTexture = initialTexture;
}
}
public void ReInitializeVideo() {
if (screen != null) {
screen.sharedMaterial.mainTexture = initialTexture;
}
if (videoPlayerPtr == IntPtr.Zero) {
CreatePlayer();
}
Init();
}
void OnDestroy() {
CleanupVideo();
}
void OnApplicationPause(bool bPause) {
if (videoPlayerPtr != IntPtr.Zero) {
if (bPause) {
playOnResume = !IsPaused;
PauseVideo(videoPlayerPtr);
} else {
if (playOnResume) {
PlayVideo(videoPlayerPtr);
}
}
}
}
void UpdateMaterial() {
// Don't render if not initialized.
if (videoPlayerPtr == IntPtr.Zero) {
return;
}
texWidth = GetWidth(videoPlayerPtr);
texHeight = GetHeight(videoPlayerPtr);
int externalTextureId = GetExternalSurfaceTextureId(videoPlayerPtr);
if (surfaceTexture != null
&& surfaceTexture.GetNativeTexturePtr().ToInt32() != externalTextureId) {
Destroy(surfaceTexture);
surfaceTexture = null;
}
if (surfaceTexture == null && externalTextureId != 0) {
Debug.Log("Creating external texture with surface texture id " + externalTextureId);
// Size of this texture doesn't really matter and can change on the fly anyway.
surfaceTexture = Texture2D.CreateExternalTexture(4, 4, TextureFormat.RGBA32,
false, false, new System.IntPtr(externalTextureId));
}
if (surfaceTexture == null) {
return;
}
// Don't swap the textures if the video ended.
if (PlayerState == VideoPlayerState.Ended) {
return;
}
if (screen == null) {
Debug.LogError("GvrVideoPlayerTexture: No screen to display the video is set.");
return;
}
if (screen != null) {
// Unity may build new a new material instance when assigning
// material.x which can lead to duplicating materials each frame
// whereas using the shared material will modify the original material.
// Update the material's texture if it is different.
if (screen.sharedMaterial.mainTexture == null ||
screen.sharedMaterial.mainTexture.GetNativeTexturePtr() != surfaceTexture.GetNativeTexturePtr()) {
screen.sharedMaterial.mainTexture = surfaceTexture;
}
screen.sharedMaterial.SetMatrix(videoMatrixPropertyId, videoMatrix);
}
}
private void OnRestartVideoEvent(int eventId) {
if (eventId == (int)VideoEvents.VideoReady) {
Debug.Log("Restarting video complete.");
RemoveOnVideoEventCallback(OnRestartVideoEvent);
}
}
/// <summary>
/// Resets the video player.
/// </summary>
public void RestartVideo() {
SetOnVideoEventCallback(OnRestartVideoEvent);
string theUrl = ProcessURL();
InitVideoPlayer(videoPlayerPtr, (int) videoType, theUrl,
videoContentID,
videoProviderId,
useSecurePath,
true);
framecount = 0;
lastVideoTimestamp = -1;
}
public void SetCurrentVolume(int val) {
SetCurrentVolume(videoPlayerPtr, val);
}
/// <summary>
/// Initialize the video player.
/// </summary>
/// <returns>true if successful</returns>
public bool Init() {
if (initialized) {
Debug.Log("Skipping initialization: video player already loaded");
return true;
}
if (videoURL == null || videoURL.Length == 0) {
Debug.LogError("Cannot initialize with null videoURL");
return false;
}
videoURL = videoURL == null ? "" : videoURL.Trim();
videoContentID = videoContentID == null ? "" : videoContentID.Trim();
videoProviderId = videoProviderId == null ? "" : videoProviderId.Trim();
SetInitialResolution(videoPlayerPtr, (int) initialResolution);
string theUrl = ProcessURL();
Debug.Log("Playing " + videoType + " " + theUrl);
Debug.Log("videoContentID = " + videoContentID);
Debug.Log("videoProviderId = " + videoProviderId);
videoPlayerPtr = InitVideoPlayer(videoPlayerPtr, (int) videoType, theUrl,
videoContentID, videoProviderId,
useSecurePath, false);
IssuePlayerEvent(RenderCommand.InitializePlayer);
initialized = true;
framecount = 0;
lastVideoTimestamp = -1;
return videoPlayerPtr != IntPtr.Zero;
}
public bool Play() {
if (!initialized) {
Init();
}
if (videoPlayerPtr != IntPtr.Zero && IsVideoReady(videoPlayerPtr)) {
return PlayVideo(videoPlayerPtr) == 0;
} else {
Debug.LogError("Video player not ready to Play!");
return false;
}
}
public bool Pause() {
if (!initialized) {
Init();
}
if (VideoReady) {
return PauseVideo(videoPlayerPtr) == 0;
} else {
Debug.LogError("Video player not ready to Pause!");
return false;
}
}
/// <summary>
/// Adjusts the aspect ratio.
/// </summary>
/// <remarks>
/// This adjusts the transform scale to match the aspect
/// ratio of the texture.
/// </remarks>
private void AdjustAspectRatio() {
float aspectRatio = AspectRatio;
if (aspectRatio == 0.0f) {
return;
}
// set the y scale based on the x value
Vector3 newscale = transform.localScale;
newscale.y = Mathf.Min(newscale.y, newscale.x / aspectRatio);
transform.localScale = newscale;
}
private void UpdateStatusText() {
float fps = CurrentPosition > 0 ?
(framecount / (CurrentPosition / 1000f)) : CurrentPosition;
string status = texWidth + " x " + texHeight + " buffer: " +
(BufferedPosition / 1000) + " " + PlayerState + " fps: " + fps;
if (statusText != null) {
if (statusText.text != status) {
statusText.text = status;
}
}
}
/// <summary>
/// Issues the player event.
/// </summary>
/// <param name="evt">The event to send to the video player
/// instance.
/// </param>
private void IssuePlayerEvent(RenderCommand evt) {
if (renderEventFunction == IntPtr.Zero) {
renderEventFunction = GetRenderEventFunc();
}
if (renderEventFunction == IntPtr.Zero || evt == RenderCommand.None) {
Debug.LogError("Attempt to IssuePlayerEvent before renderEventFunction ready.");
return;
}
GL.IssuePluginEvent(renderEventFunction, videoPlayerEventBase + (int)evt);
}
void Update() {
while (ExecuteOnMainThread.Count > 0) {
ExecuteOnMainThread.Dequeue().Invoke();
}
if (VideoReady) {
IssuePlayerEvent(RenderCommand.UpdateVideo);
GetVideoMatrix(videoPlayerPtr, videoMatrixRaw);
videoMatrix = GvrMathHelpers.ConvertFloatArrayToMatrix(videoMatrixRaw);
long vidTimestamp = GetVideoTimestampNs(videoPlayerPtr);
if (vidTimestamp != lastVideoTimestamp) {
framecount++;
}
lastVideoTimestamp = vidTimestamp;
UpdateMaterial();
if (adjustAspectRatio) {
AdjustAspectRatio();
}
if ((int) framecount % 30 == 0) {
UpdateStatusText();
}
long bp = BufferedPosition;
if (bp != lastBufferedPosition) {
lastBufferedPosition = bp;
UpdateStatusText();
}
}
}
public void RemoveOnVideoEventCallback(Action<int> callback) {
if (onEventCallbacks != null) {
onEventCallbacks.Remove(callback);
}
}
public void SetOnVideoEventCallback(Action<int> callback) {
if (onEventCallbacks == null) {
onEventCallbacks = new List<Action<int>>();
}
onEventCallbacks.Add(callback);
SetOnVideoEventCallback(videoPlayerPtr, InternalOnVideoEventCallback,
ToIntPtr(this));
}
internal void FireVideoEvent(int eventId) {
if (onEventCallbacks == null) {
return;
}
// Copy the collection so the callbacks can remove themselves from the list.
Action<int>[] cblist = onEventCallbacks.ToArray();
foreach (Action<int> cb in cblist) {
try {
cb(eventId);
} catch (Exception e) {
Debug.LogError("exception calling callback: " + e);
}
}
}
[AOT.MonoPInvokeCallback(typeof(OnVideoEventCallback))]
static void InternalOnVideoEventCallback(IntPtr cbdata, int eventId) {
if (cbdata == IntPtr.Zero) {
return;
}
GvrVideoPlayerTexture player;
var gcHandle = GCHandle.FromIntPtr(cbdata);
try {
player = (GvrVideoPlayerTexture) gcHandle.Target;
}
catch (InvalidCastException e) {
Debug.LogError("GC Handle pointed to unexpected type: " +
gcHandle.Target + ". Expected " +
typeof(GvrVideoPlayerTexture));
throw e;
}
if (player != null) {
ExecuteOnMainThread.Enqueue(() => player.FireVideoEvent(eventId));
}
}
public void SetOnExceptionCallback(Action<string, string> callback) {
if (onExceptionCallbacks == null) {
onExceptionCallbacks = new List<Action<string, string>>();
SetOnExceptionCallback(videoPlayerPtr, InternalOnExceptionCallback,
ToIntPtr(this));
}
onExceptionCallbacks.Add(callback);
}
[AOT.MonoPInvokeCallback(typeof(OnExceptionCallback))]
static void InternalOnExceptionCallback(string type, string msg,
IntPtr cbdata) {
if (cbdata == IntPtr.Zero) {
return;
}
GvrVideoPlayerTexture player;
var gcHandle = GCHandle.FromIntPtr(cbdata);
try {
player = (GvrVideoPlayerTexture) gcHandle.Target;
}
catch (InvalidCastException e) {
Debug.LogError("GC Handle pointed to unexpected type: " +
gcHandle.Target + ". Expected " +
typeof(GvrVideoPlayerTexture));
throw e;
}
if (player != null) {
ExecuteOnMainThread.Enqueue(() => player.FireOnException(type, msg));
}
}
internal void FireOnException(string type, string msg) {
if (onExceptionCallbacks == null) {
return;
}
foreach (Action<string, string> cb in onExceptionCallbacks) {
try {
cb(type, msg);
} catch (Exception e) {
Debug.LogError("exception calling callback: " + e);
}
}
}
internal static IntPtr ToIntPtr(System.Object obj) {
GCHandle handle = GCHandle.Alloc(obj);
return GCHandle.ToIntPtr(handle);
}
internal string ProcessURL() {
return videoURL.Replace("${Application.dataPath}", Application.dataPath);
}
internal delegate void OnVideoEventCallback(IntPtr cbdata, int eventId);
internal delegate void OnExceptionCallback(string type, string msg,
IntPtr cbdata);
#if UNITY_ANDROID && !UNITY_EDITOR
private const string dllName = "gvrvideo";
[DllImport(dllName)]
private static extern IntPtr GetRenderEventFunc();
[DllImport(dllName)]
private static extern void SetExternalTextures(IntPtr videoPlayerPtr,
int[] texIds,
int size,
int w,
int h);
[DllImport(dllName)]
private static extern IntPtr GetRenderableTextureId(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern int GetExternalSurfaceTextureId(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern void GetVideoMatrix(IntPtr videoPlayerPtr,
float[] videoMatrix);
[DllImport(dllName)]
private static extern long GetVideoTimestampNs(IntPtr videoPlayerPtr);
// Keep public so we can check for the dll being present at runtime.
[DllImport(dllName)]
public static extern IntPtr CreateVideoPlayer();
// Keep public so we can check for the dll being present at runtime.
[DllImport(dllName)]
public static extern void DestroyVideoPlayer(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern int GetVideoPlayerEventBase(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern IntPtr InitVideoPlayer(IntPtr videoPlayerPtr,
int videoType,
string videoURL,
string contentID,
string providerId,
bool useSecurePath,
bool useExisting);
[DllImport(dllName)]
private static extern void SetInitialResolution(IntPtr videoPlayerPtr,
int initialResolution);
[DllImport(dllName)]
private static extern int GetPlayerState(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern int GetWidth(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern int GetHeight(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern int PlayVideo(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern int PauseVideo(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern bool IsVideoReady(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern bool IsVideoPaused(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern long GetDuration(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern long GetBufferedPosition(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern long GetCurrentPosition(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern void SetCurrentPosition(IntPtr videoPlayerPtr,
long pos);
[DllImport(dllName)]
private static extern int GetBufferedPercentage(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern int GetMaxVolume(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern int GetCurrentVolume(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern void SetCurrentVolume(IntPtr videoPlayerPtr,
int value);
[DllImport(dllName)]
private static extern int GetStereoMode(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern bool HasProjectionData(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern bool SetVideoPlayerSupportClassname(
IntPtr videoPlayerPtr,
string classname);
[DllImport(dllName)]
private static extern IntPtr GetRawPlayer(IntPtr videoPlayerPtr);
[DllImport(dllName)]
private static extern void SetOnVideoEventCallback(IntPtr videoPlayerPtr,
OnVideoEventCallback callback,
IntPtr callback_arg);
[DllImport(dllName)]
private static extern void SetOnExceptionCallback(IntPtr videoPlayerPtr,
OnExceptionCallback callback,
IntPtr callback_arg);
#else
private const string NOT_IMPLEMENTED_MSG =
"Not implemented on this platform";
private static IntPtr GetRenderEventFunc() {
Debug.Log(NOT_IMPLEMENTED_MSG);
return IntPtr.Zero;
}
private static void SetExternalTextures(IntPtr videoPlayerPtr,
int[] texIds,
int size,
int w,
int h) {
Debug.Log(NOT_IMPLEMENTED_MSG);
}
private static IntPtr GetRenderableTextureId(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return IntPtr.Zero;
}
private static int GetExternalSurfaceTextureId(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return 0;
}
private static void GetVideoMatrix(IntPtr videoPlayerPtr,
float[] videoMatrix) {
Debug.Log(NOT_IMPLEMENTED_MSG);
}
private static long GetVideoTimestampNs(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return -1;
}
// Make this public so we can test the loading of the DLL.
public static IntPtr CreateVideoPlayer() {
Debug.Log(NOT_IMPLEMENTED_MSG);
return IntPtr.Zero;
}
// Make this public so we can test the loading of the DLL.
public static void DestroyVideoPlayer(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
}
private static int GetVideoPlayerEventBase(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return 0;
}
private static IntPtr InitVideoPlayer(IntPtr videoPlayerPtr, int videoType,
string videoURL,
string contentID,
string providerId,
bool useSecurePath,
bool useExisting) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return IntPtr.Zero;
}
private static void SetInitialResolution(IntPtr videoPlayerPtr,
int initialResolution) {
Debug.Log(NOT_IMPLEMENTED_MSG);
}
private static int GetPlayerState(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return -1;
}
private static int GetWidth(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return -1;
}
private static int GetHeight(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return -1;
}
private static int PlayVideo(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return 0;
}
private static int PauseVideo(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return 0;
}
private static bool IsVideoReady(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return false;
}
private static bool IsVideoPaused(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return true;
}
private static long GetDuration(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return -1;
}
private static long GetBufferedPosition(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return -1;
}
private static long GetCurrentPosition(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return -1;
}
private static void SetCurrentPosition(IntPtr videoPlayerPtr, long pos) {
Debug.Log(NOT_IMPLEMENTED_MSG);
}
private static int GetBufferedPercentage(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return 0;
}
private static int GetMaxVolume(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return 0;
}
private static int GetCurrentVolume(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return 0;
}
private static void SetCurrentVolume(IntPtr videoPlayerPtr, int value) {
Debug.Log(NOT_IMPLEMENTED_MSG);
}
private static int GetStereoMode(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return -1;
}
private static bool HasProjectionData(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return false;
}
private static bool SetVideoPlayerSupportClassname(IntPtr videoPlayerPtr,
string classname) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return false;
}
private static IntPtr GetRawPlayer(IntPtr videoPlayerPtr) {
Debug.Log(NOT_IMPLEMENTED_MSG);
return IntPtr.Zero;
}
private static void SetOnVideoEventCallback(IntPtr videoPlayerPtr,
OnVideoEventCallback callback,
IntPtr callback_arg) {
Debug.Log(NOT_IMPLEMENTED_MSG);
}
private static void SetOnExceptionCallback(IntPtr videoPlayerPtr,
OnExceptionCallback callback,
IntPtr callback_arg) {
Debug.Log(NOT_IMPLEMENTED_MSG);
}
#endif // UNITY_ANDROID && !UNITY_EDITOR
}