天津23维预案
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

601 lines
14 KiB

2 years ago
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IPHONE || UNITY_IOS || UNITY_TVOS
#if UNITY_5
#if !UNITY_5_0 && !UNITY_5_1
#define AVPROVIDEO_ISSUEPLUGINEVENT_UNITY52
#endif
#endif
using UnityEngine;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using AOT;
//-----------------------------------------------------------------------------
// Copyright 2015-2016 RenderHeads Ltd. All rights reserverd.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo
{
// IMediaInfo
//
// float GetDurationMs();
// int GetVideoWidth();
// int GetVideoHeight();
//
// float GetVideoPlaybackRate();
//
// bool HasVideo();
// bool HasAudio();
// BaseMediaPlayer
//
// public abstract String GetVersion();
//
// public abstract bool OpenVideoFromFile( string path );
// public abstract void CloseVideo();
//
// public abstract void SetLooping( bool bLooping );
// public abstract bool IsLooping();
//
// public abstract bool HasMetaData();
// public abstract bool CanPlay();
// public abstract void Play();
// public abstract void Pause();
// public abstract void Stop();
// public abstract void Rewind();
//
// public abstract void Seek(float timeMs);
// public abstract float GetCurrentTimeMs();
//
// public abstract float GetDurationMs();
// public abstract int GetVideoWidth();
// public abstract int GetVideoHeight();
// public abstract float GetVideoPlaybackRate();
//
// public abstract bool IsSeeking();
// public abstract bool IsPlaying();
// public abstract bool IsPaused();
// public abstract bool IsFinished();
// public abstract bool IsBuffering();
//
// public abstract Texture GetTexture();
// public abstract int GetTextureFrameCount();
// public abstract bool RequiresVerticalFlip();
//
//
// public abstract void MuteAudio(bool bMuted);
// public abstract void SetVolume(float volume);
// public abstract float GetVolume();
//
// public abstract void Update();
// public abstract void Render();
// public abstract void Dispose();
public class OSXMediaPlayer : BaseMediaPlayer
{
#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
private const string PluginName = "AVProVideo";
#elif UNITY_IPHONE || UNITY_IOS || UNITY_TVOS
private const string PluginName = "__Internal";
#endif
// Native Interface
private enum AVPPluginEventType
{
Nop,
PlayerUpdate,
PlayerShutdown,
FreeTextureResources,
}
private enum AVPPlayerStatus
{
Unknown,
ReadyToPlay,
Playing,
Finished,
Seeking,
Failed
}
private enum AVPLogFlag
{
Error = 1 << 0,
Warning = 1 << 1,
Info = 1 << 2,
Debug = 1 << 3,
Verbose = 1 << 4,
};
private enum AVPLogLevel
{
Off = 0,
Error = AVPLogFlag.Error,
Warning = AVPLogFlag.Error | AVPLogFlag.Warning,
Info = AVPLogFlag.Error | AVPLogFlag.Warning | AVPLogFlag.Info,
Debug = AVPLogFlag.Error | AVPLogFlag.Warning | AVPLogFlag.Info | AVPLogFlag.Debug,
Verbose = AVPLogFlag.Error | AVPLogFlag.Warning | AVPLogFlag.Info | AVPLogFlag.Debug | AVPLogFlag.Verbose,
All = -1
};
[DllImport(PluginName)]
private static extern string AVPGetVersion();
#if AVPROVIDEO_ISSUEPLUGINEVENT_UNITY52
[DllImport(PluginName)]
private static extern IntPtr AVPGetRenderEventFunc();
#endif
[DllImport(PluginName)]
private static extern double AVPPlayerGetCurrentTime(IntPtr player);
[DllImport(PluginName)]
private static extern double AVPPlayerGetDuration(IntPtr player);
[DllImport(PluginName)]
private static extern int AVPPlayerGetFrameCount(IntPtr player);
[DllImport(PluginName)]
private static extern double AVPPlayerGetFrameRate(IntPtr player);
[DllImport(PluginName)]
private static extern double AVPPlayerGetNominalFrameRate(IntPtr player);
[DllImport(PluginName)]
private static extern int AVPPlayerGetHandle(IntPtr player);
[DllImport(PluginName)]
private static extern AVPPlayerStatus AVPPlayerGetStatus(IntPtr player);
[DllImport(PluginName)]
private static extern bool AVPlayerIsBuffering(IntPtr player);
[DllImport(PluginName)]
private static extern IntPtr AVPPlayerGetTextureHandle(IntPtr player);
[DllImport(PluginName)]
private static extern void AVPPlayerGetTextureSize(IntPtr player, out int width, out int height);
[DllImport(PluginName)]
private static extern bool AVPPlayerTextureIsFlipped(IntPtr player);
[DllImport(PluginName)]
private static extern bool AVPPlayerTextureSizeHasChanged(IntPtr player);
[DllImport(PluginName)]
private static extern float AVPPlayerGetVolume(IntPtr player);
[DllImport(PluginName)]
private static extern bool AVPPlayerHasAudio(IntPtr player);
[DllImport(PluginName)]
private static extern bool AVPPlayerHasVideo(IntPtr player);
[DllImport(PluginName)]
private static extern bool AVPPlayerHasMetaData(IntPtr player);
[DllImport(PluginName)]
private static extern bool AVPPlayerIsLooping(IntPtr player);
[DllImport(PluginName)]
private static extern void AVPPlayerSetLooping(IntPtr player, bool looping);
[DllImport(PluginName)]
private static extern bool AVPPlayerIsMuted(IntPtr player);
[DllImport(PluginName)]
private static extern void AVPPlayerSetMuted(IntPtr player, bool muted);
[DllImport(PluginName)]
private static extern void AVPPlayerSetVolume(IntPtr player, float volume);
[DllImport(PluginName)]
private static extern IntPtr AVPPlayerNew();
[DllImport(PluginName)]
private static extern IntPtr AVPPlayerRelease(IntPtr player);
[DllImport(PluginName)]
private static extern bool AVPPlayerOpenFile(IntPtr player, string path);
[DllImport(PluginName)]
private static extern bool AVPPlayerOpenURL(IntPtr player, string url);
[DllImport(PluginName)]
private static extern void AVPPlayerClose(IntPtr player);
[DllImport(PluginName)]
private static extern void AVPPlayerPlay(IntPtr player);
[DllImport(PluginName)]
private static extern void AVPPlayerPause(IntPtr player);
[DllImport(PluginName)]
private static extern void AVPPlayerSeekToTime(IntPtr player, double time, bool fast);
[DllImport(PluginName)]
private static extern float AVPPlayerGetPlaybackRate(IntPtr player);
[DllImport(PluginName)]
private static extern void AVPPlayerSetPlaybackRate(IntPtr player, float rate);
[DllImport(PluginName)]
private static extern void AVPPluginRegister();
[DllImport(PluginName)]
private static extern void AVPPluginInitialise();
[DllImport(PluginName)]
private static extern void AVPPluginSetDebugLogFunction(IntPtr fn);
// MediaPlayer Interface
private static bool _initialised = false;
#if AVPROVIDEO_ISSUEPLUGINEVENT_UNITY52
private static IntPtr _renderEventFunc = IntPtr.Zero;
#endif
#if UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
#endif
private delegate void DebugLogCallbackDelegate(int level, int flags, string str);
#if UNITY_IPHONE || UNITY_IOS || UNITY_TVOS
[MonoPInvokeCallback(typeof(DebugLogCallbackDelegate))]
#endif
private static void DebugLogCallback(int level, int flags, string str)
{
if ((flags & (int)AVPLogFlag.Error) == (int)AVPLogFlag.Error)
{
Debug.LogError(str);
}
else if ((flags & (int)AVPLogFlag.Warning) == (int)AVPLogFlag.Warning)
{
Debug.LogWarning(str);
}
else
{
Debug.Log(str);
}
}
private static void IssuePluginEvent(AVPPluginEventType type, int param)
{
// Build eventId from the type and param.
int eventId = 0x0FA60000 | ((int)type << 12);
switch (type)
{
case AVPPluginEventType.PlayerUpdate:
case AVPPluginEventType.PlayerShutdown:
eventId |= param & 0xfff;
break;
}
#if AVPROVIDEO_ISSUEPLUGINEVENT_UNITY52
GL.IssuePluginEvent(_renderEventFunc, eventId);
#else
GL.IssuePluginEvent(eventId);
#endif
}
static void Initialise()
{
if (!_initialised)
{
_initialised = true;
#if ((UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX) && !UNITY_5) || (UNITY_IPHONE || UNITY_IOS || UNITY_TVOS)
AVPPluginRegister();
#endif
DebugLogCallbackDelegate callbackDelegate = new DebugLogCallbackDelegate(DebugLogCallback);
IntPtr func = Marshal.GetFunctionPointerForDelegate(callbackDelegate);
AVPPluginSetDebugLogFunction(func);
AVPPluginInitialise();
#if AVPROVIDEO_ISSUEPLUGINEVENT_UNITY52
_renderEventFunc = AVPGetRenderEventFunc();
#endif
}
}
private IntPtr _player = IntPtr.Zero; // Handle to the native player.
private Texture2D _texture = null;
private IntPtr _native = IntPtr.Zero;
private int _width = 0;
private int _height = 0;
private bool _isMetaDataReady = false;
static OSXMediaPlayer()
{
Initialise();
}
public OSXMediaPlayer()
{
_player = AVPPlayerNew();
}
// BaseMediaPlayer Overrides
public override string GetVersion()
{
return AVPGetVersion();
}
public override bool OpenVideoFromFile(string path)
{
if (path.StartsWith("http://") || path.StartsWith("https://") || path.StartsWith("file://"))
{
return AVPPlayerOpenURL(_player, path);
}
else
{
return AVPPlayerOpenFile(_player, path);
}
}
public override void CloseVideo()
{
if (_texture != null)
{
// Have to update with zero to release Metal textures!
_texture.UpdateExternalTexture(IntPtr.Zero);
Texture2D.Destroy(_texture);
_texture = null;
}
_width = 0;
_height = 0;
_native = IntPtr.Zero;
_isMetaDataReady = false;
AVPPlayerClose(_player);
}
public override bool IsLooping()
{
return AVPPlayerIsLooping(_player);
}
public override void SetLooping(bool looping)
{
AVPPlayerSetLooping(_player, looping);
}
public override bool HasAudio()
{
return AVPPlayerHasAudio(_player);
}
public override bool HasVideo()
{
return AVPPlayerHasVideo(_player);
}
public override bool HasMetaData()
{
return _isMetaDataReady;
}
public override bool CanPlay()
{
return AVPPlayerGetStatus(_player) >= AVPPlayerStatus.ReadyToPlay;
}
public override void Play()
{
AVPPlayerPlay(_player);
}
public override void Pause()
{
AVPPlayerPause(_player);
}
public override void Stop()
{
AVPPlayerPause(_player);
}
public override void Rewind()
{
AVPPlayerSeekToTime(_player, 0.0, true);
}
public override void Seek(float ms)
{
AVPPlayerSeekToTime(_player, ms / 1000.0, false);
}
public override void SeekFast(float ms)
{
AVPPlayerSeekToTime(_player, ms / 1000.0, true);
}
public override float GetCurrentTimeMs()
{
return (float)(AVPPlayerGetCurrentTime(_player) * 1000.0f);
}
public override void SetPlaybackRate(float rate)
{
AVPPlayerSetPlaybackRate(_player, rate);
}
public override float GetPlaybackRate()
{
return AVPPlayerGetPlaybackRate(_player);
}
public override float GetDurationMs()
{
return (float)(AVPPlayerGetDuration(_player) * 1000.0f);
}
public override int GetVideoWidth()
{
return _width;
}
public override int GetVideoHeight()
{
return _height;
}
public override float GetVideoPlaybackRate()
{
return (float)AVPPlayerGetFrameRate(_player);
}
public override bool IsSeeking()
{
return AVPPlayerGetStatus(_player) == AVPPlayerStatus.Seeking;
}
public override bool IsPlaying()
{
return AVPPlayerGetStatus(_player) == AVPPlayerStatus.Playing;
}
public override bool IsPaused()
{
return AVPPlayerGetStatus(_player) == AVPPlayerStatus.ReadyToPlay;
}
public override bool IsFinished()
{
return AVPPlayerGetStatus(_player) == AVPPlayerStatus.Finished;
}
public override bool IsBuffering()
{
return AVPlayerIsBuffering(_player);
}
public override Texture GetTexture()
{
return _texture;
}
public override int GetTextureFrameCount()
{
return AVPPlayerGetFrameCount(_player);
}
public override bool RequiresVerticalFlip()
{
return AVPPlayerTextureIsFlipped(_player);
}
public override bool IsMuted()
{
return AVPPlayerIsMuted(_player);
}
public override void MuteAudio( bool bMute )
{
AVPPlayerSetMuted(_player, bMute);
}
public override void SetVolume(float volume)
{
AVPPlayerSetVolume(_player, volume);
}
public override float GetVolume()
{
return AVPPlayerGetVolume(_player);
}
public override void Render()
{
// Nothing to do!
}
public override void Update()
{
// Only call this once per frame!
OSXMediaPlayer.IssuePluginEvent(AVPPluginEventType.PlayerUpdate, AVPPlayerGetHandle(_player));
int width = 0;
int height = 0;
AVPPlayerGetTextureSize(_player, out width, out height);
IntPtr native = AVPPlayerGetTextureHandle(_player);
if (_texture != null && (_width != width || _height != height))
{
// Have to update with zero to release Metal textures!
_texture.UpdateExternalTexture(IntPtr.Zero);
Texture2D.Destroy(_texture);
_texture = null;
}
if (_texture == null && native != IntPtr.Zero)
{
TextureFormat format = TextureFormat.BGRA32;
bool mipmap = false;
bool linear = false;
_texture = Texture2D.CreateExternalTexture(width, height, format, mipmap, linear, native);
_width = width;
_height = height;
_native = native;
ApplyTextureProperties(_texture);
}
else if (_texture != null && native != _native)
{
_texture.UpdateExternalTexture(native);
_native = native;
}
// Check for meta data to become available
if (!_isMetaDataReady)
{
if (AVPPlayerHasMetaData(_player) || CanPlay())
{
if (HasVideo())
{
if (width > 0 && height > 0)
{
if (Mathf.Max(width, height) > SystemInfo.maxTextureSize)
{
Debug.LogError("[AVProVideo] Video dimensions larger than maxTextureSize");
}
_isMetaDataReady = true;
}
}
else if (HasAudio())
{
_isMetaDataReady = true;
}
}
}
}
public override void Dispose()
{
if (_texture != null)
{
// Have to update with zero to release Metal textures!
_texture.UpdateExternalTexture(IntPtr.Zero);
Texture2D.Destroy(_texture);
_texture = null;
}
if (_player != IntPtr.Zero)
{
OSXMediaPlayer.IssuePluginEvent(AVPPluginEventType.FreeTextureResources, AVPPlayerGetHandle(_player));
AVPPlayerRelease(_player);
_player = IntPtr.Zero;
}
}
}
}
#endif