|
@@ -0,0 +1,1477 @@
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#define AVPROVIDEO_SUPPORT_LIVEEDITMODE
|
|
|
+using UnityEngine;
|
|
|
+using UnityEngine.Serialization;
|
|
|
+using System.Collections;
|
|
|
+using System.Collections.Generic;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+namespace RenderHeads.Media.AVProVideo
|
|
|
+{
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+#if AVPROVIDEO_SUPPORT_LIVEEDITMODE
|
|
|
+ [ExecuteInEditMode]
|
|
|
+#endif
|
|
|
+ [AddComponentMenu("AVPro Video/Media Player", -100)]
|
|
|
+ [HelpURL("https://www.renderheads.com/products/avpro-video/")]
|
|
|
+ public partial class MediaPlayer : MonoBehaviour
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ [SerializeField] MediaSource _mediaSource = MediaSource.Reference;
|
|
|
+ public MediaSource MediaSource { get { return _mediaSource; } internal set { _mediaSource = value; } }
|
|
|
+
|
|
|
+ [SerializeField] MediaReference _mediaReference = null;
|
|
|
+ public MediaReference MediaReference { get { return _mediaReference; } internal set { _mediaReference = value; } }
|
|
|
+
|
|
|
+ [SerializeField] MediaPath _mediaPath = new MediaPath();
|
|
|
+ public MediaPath MediaPath { get { return _mediaPath; } internal set { _mediaPath = value; } }
|
|
|
+
|
|
|
+ [SerializeField] MediaHints _fallbackMediaHints = MediaHints.Default;
|
|
|
+ public MediaHints FallbackMediaHints { get { return _fallbackMediaHints; } set { _fallbackMediaHints = value; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_AutoOpen")]
|
|
|
+ [SerializeField] bool _autoOpen = true;
|
|
|
+ public bool AutoOpen { get { return _autoOpen; } set { _autoOpen = value; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_AutoStart")]
|
|
|
+ [SerializeField] bool _autoPlayOnStart = true;
|
|
|
+ public bool AutoStart { get { return _autoPlayOnStart; } set { _autoPlayOnStart = value; } }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_Loop")]
|
|
|
+ [SerializeField] bool _loop = false;
|
|
|
+ public bool Loop
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return (_controlInterface != null) ? _controlInterface.IsLooping() : _loop;
|
|
|
+ }
|
|
|
+
|
|
|
+ set
|
|
|
+ {
|
|
|
+ _loop = value;
|
|
|
+ if (_controlInterface != null)
|
|
|
+ _controlInterface.SetLooping(_loop);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_Volume")]
|
|
|
+ [Range(0.0f, 1.0f)]
|
|
|
+ [SerializeField] float _audioVolume = 1.0f;
|
|
|
+ public virtual float AudioVolume
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return (_controlInterface != null) ? _controlInterface.GetVolume() : _audioVolume;
|
|
|
+ }
|
|
|
+
|
|
|
+ set
|
|
|
+ {
|
|
|
+ _audioVolume = Mathf.Clamp01(value);
|
|
|
+ if (_controlInterface != null)
|
|
|
+ _controlInterface.SetVolume(_audioVolume);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_Balance")]
|
|
|
+ [Range(-1.0f, 1.0f)]
|
|
|
+ [SerializeField] float _audioBalance = 0.0f;
|
|
|
+ public float AudioBalance
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return (_controlInterface != null) ? _controlInterface.GetBalance() : _audioBalance;
|
|
|
+ }
|
|
|
+
|
|
|
+ set
|
|
|
+ {
|
|
|
+ _audioBalance = Mathf.Clamp(value, -1f, 1f);
|
|
|
+ if (_controlInterface != null)
|
|
|
+ _controlInterface.SetBalance(_audioBalance);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_Muted")]
|
|
|
+ [SerializeField] bool _audioMuted = false;
|
|
|
+ public virtual bool AudioMuted
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return (_controlInterface != null) ? _controlInterface.IsMuted() : _audioMuted;
|
|
|
+ }
|
|
|
+
|
|
|
+ set
|
|
|
+ {
|
|
|
+ _audioMuted = value;
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ #if !UNITY_EDITOR
|
|
|
+ _controlInterface.MuteAudio(_audioMuted);
|
|
|
+ #else
|
|
|
+ _controlInterface.MuteAudio(_audioMuted || UnityEditor.EditorUtility.audioMasterMute);
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private AudioSource _audioSource = null;
|
|
|
+ public AudioSource AudioSource { get { return _audioSource; } internal set { _audioSource = value; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_PlaybackRate")]
|
|
|
+ [Range(-4.0f, 4.0f)]
|
|
|
+ [SerializeField] float _playbackRate = 1.0f;
|
|
|
+ public float PlaybackRate
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ return (_controlInterface != null) ? _controlInterface.GetPlaybackRate() : _playbackRate;
|
|
|
+ }
|
|
|
+
|
|
|
+ set
|
|
|
+ {
|
|
|
+ _playbackRate = value;
|
|
|
+ if (_controlInterface != null)
|
|
|
+ _controlInterface.SetPlaybackRate(_playbackRate);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_Resample")]
|
|
|
+ [SerializeField] bool _useResampler = false;
|
|
|
+ public bool UseResampler { get { return _useResampler; } set { _useResampler = value; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_ResampleMode")]
|
|
|
+ [SerializeField] Resampler.ResampleMode _resampleMode = Resampler.ResampleMode.POINT;
|
|
|
+ public Resampler.ResampleMode ResampleMode { get { return _resampleMode; } set { _resampleMode = value; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_ResampleBufferSize")]
|
|
|
+ [Range(3, 10)]
|
|
|
+ [SerializeField] int _resampleBufferSize = 5;
|
|
|
+ public int ResampleBufferSize { get { return _resampleBufferSize; } set { _resampleBufferSize = value; } }
|
|
|
+
|
|
|
+ private Resampler _resampler = null;
|
|
|
+ public Resampler FrameResampler { get { return _resampler; } }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_videoMapping")]
|
|
|
+ [SerializeField] VideoMapping _videoMapping = VideoMapping.Unknown;
|
|
|
+ public VideoMapping VideoLayoutMapping { get { return _videoMapping; } set { _videoMapping = value; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_FilterMode")]
|
|
|
+ [SerializeField] FilterMode _textureFilterMode = FilterMode.Bilinear;
|
|
|
+ public FilterMode TextureFilterMode
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ FilterMode filterMode = FilterMode.Point;
|
|
|
+ TextureWrapMode textureWrapMode = TextureWrapMode.Repeat;
|
|
|
+ int anisoLevel = 0;
|
|
|
+ _controlInterface.GetTextureProperties(out filterMode, out textureWrapMode, out anisoLevel);
|
|
|
+ return filterMode;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return _textureFilterMode;
|
|
|
+ }
|
|
|
+
|
|
|
+ set
|
|
|
+ {
|
|
|
+ _textureFilterMode = value;
|
|
|
+ if (_controlInterface != null)
|
|
|
+ _controlInterface.SetTextureProperties(_textureFilterMode, _textureWrapMode, _textureAnisoLevel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_WrapMode")]
|
|
|
+ [SerializeField] TextureWrapMode _textureWrapMode = TextureWrapMode.Clamp;
|
|
|
+ public TextureWrapMode TextureWrapMode
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ FilterMode filterMode = FilterMode.Point;
|
|
|
+ TextureWrapMode textureWrapMode = TextureWrapMode.Repeat;
|
|
|
+ int anisoLevel = 0;
|
|
|
+ _controlInterface.GetTextureProperties(out filterMode, out textureWrapMode, out anisoLevel);
|
|
|
+ return textureWrapMode;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return _textureWrapMode;
|
|
|
+ }
|
|
|
+
|
|
|
+ set
|
|
|
+ {
|
|
|
+ _textureWrapMode = value;
|
|
|
+ if (_controlInterface != null)
|
|
|
+ _controlInterface.SetTextureProperties(_textureFilterMode, _textureWrapMode, _textureAnisoLevel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_AnisoLevel")]
|
|
|
+ [Range(0, 16)]
|
|
|
+ [SerializeField] int _textureAnisoLevel = 0;
|
|
|
+ public int TextureAnisoLevel
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ FilterMode filterMode = FilterMode.Point;
|
|
|
+ TextureWrapMode textureWrapMode = TextureWrapMode.Repeat;
|
|
|
+ int anisoLevel = 0;
|
|
|
+ _controlInterface.GetTextureProperties(out filterMode, out textureWrapMode, out anisoLevel);
|
|
|
+ return anisoLevel;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return _textureAnisoLevel;
|
|
|
+ }
|
|
|
+
|
|
|
+ set
|
|
|
+ {
|
|
|
+ _textureAnisoLevel = value;
|
|
|
+ if (_controlInterface != null)
|
|
|
+ _controlInterface.SetTextureProperties(_textureFilterMode, _textureWrapMode, _textureAnisoLevel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [SerializeField] bool _useVideoResolve = false;
|
|
|
+ public bool UseVideoResolve { get { return _useVideoResolve; } set { _useVideoResolve = value; } }
|
|
|
+
|
|
|
+ [SerializeField] VideoResolveOptions _videoResolveOptions = VideoResolveOptions.Create();
|
|
|
+ public VideoResolveOptions VideoResolveOptions { get { return _videoResolveOptions; } set { _videoResolveOptions = value; } }
|
|
|
+
|
|
|
+#if AVPRO_FEATURE_VIDEORESOLVE
|
|
|
+ [SerializeField] VideoResolve _videoResolve = new VideoResolve();
|
|
|
+#endif
|
|
|
+
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_LoadSubtitles")]
|
|
|
+ [SerializeField] bool _sideloadSubtitles;
|
|
|
+ public bool SideloadSubtitles { get { return _sideloadSubtitles; } set { _sideloadSubtitles = value; } }
|
|
|
+
|
|
|
+ [SerializeField] MediaPath _subtitlePath;
|
|
|
+ public MediaPath SubtitlePath { get { return _subtitlePath; } set { _subtitlePath = value; } }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_AudioHeadTransform")]
|
|
|
+ [SerializeField] Transform _audioHeadTransform;
|
|
|
+ public Transform AudioHeadTransform { set { _audioHeadTransform = value; } get { return _audioHeadTransform; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_AudioFocusEnabled")]
|
|
|
+ [SerializeField] bool _audioFocusEnabled;
|
|
|
+ public bool AudioFocusEnabled { get { return _audioFocusEnabled; } set { _audioFocusEnabled = value; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_AudioFocusTransform")]
|
|
|
+ [SerializeField] Transform _audioFocusTransform;
|
|
|
+ public Transform AudioFocusTransform { get { return _audioFocusTransform; } set { _audioFocusTransform = value; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_AudioFocusWidthDegrees")]
|
|
|
+ [SerializeField, Range(40f, 120f)] float _audioFocusWidthDegrees = 90f;
|
|
|
+ public float AudioFocusWidthDegrees { get { return _audioFocusWidthDegrees; } set { _audioFocusWidthDegrees = value; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_AudioFocusOffLevelDB")]
|
|
|
+ [SerializeField, Range(-24f, 0f)] float _audioFocusOffLevelDB = 0f;
|
|
|
+ public float AudioFocusOffLevelDB { get { return _audioFocusOffLevelDB; } set { _audioFocusOffLevelDB = value; } }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ [SerializeField] HttpHeaderData _httpHeaders = new HttpHeaderData();
|
|
|
+ public HttpHeaderData HttpHeaders { get { return _httpHeaders; } set { _httpHeaders = value; } }
|
|
|
+
|
|
|
+ [SerializeField] KeyAuthData _keyAuth = new KeyAuthData();
|
|
|
+ public KeyAuthData KeyAuth { get { return _keyAuth; } set { _keyAuth = value; } }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_events")]
|
|
|
+ [SerializeField] MediaPlayerEvent _events = null;
|
|
|
+ public MediaPlayerEvent Events
|
|
|
+ {
|
|
|
+ get
|
|
|
+ {
|
|
|
+ if (_events == null)
|
|
|
+ {
|
|
|
+ _events = new MediaPlayerEvent();
|
|
|
+ }
|
|
|
+ return _events;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_eventMask")]
|
|
|
+ [SerializeField] int _eventMask = -1;
|
|
|
+ public int EventMask { get { return _eventMask; } set { _eventMask = value; } }
|
|
|
+
|
|
|
+ [SerializeField] bool _pauseMediaOnAppPause = true;
|
|
|
+ public bool PauseMediaOnAppPause { get { return _pauseMediaOnAppPause; } set { _pauseMediaOnAppPause = value; } }
|
|
|
+
|
|
|
+ [SerializeField] bool _playMediaOnAppUnpause = true;
|
|
|
+ public bool PlayMediaOnAppUnpause { get { return _playMediaOnAppUnpause; } set { _playMediaOnAppUnpause = value; } }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_Persistent")]
|
|
|
+ [SerializeField] bool _persistent = false;
|
|
|
+ public bool Persistent { get { return _persistent; } set { _persistent = value; } }
|
|
|
+
|
|
|
+ [FormerlySerializedAs("m_forceFileFormat")]
|
|
|
+ [SerializeField] FileFormat _forceFileFormat = FileFormat.Unknown;
|
|
|
+ public FileFormat ForceFileFormat { get { return _forceFileFormat; } set { _forceFileFormat = value; } }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private BaseMediaPlayer _baseMediaPlayer;
|
|
|
+ private IMediaControl _controlInterface;
|
|
|
+ private ITextureProducer _textureInterface;
|
|
|
+ private IMediaInfo _infoInterface;
|
|
|
+ private IMediaPlayer _playerInterface;
|
|
|
+ private IMediaSubtitles _subtitlesInterface;
|
|
|
+ private IMediaCache _cacheInterface;
|
|
|
+ private IBufferedDisplay _bufferedDisplayInterface;
|
|
|
+ private IVideoTracks _videoTracksInterface;
|
|
|
+ private IAudioTracks _audioTracksInterface;
|
|
|
+ private ITextTracks _textTracksInterface;
|
|
|
+ private System.IDisposable _disposeInterface;
|
|
|
+
|
|
|
+ public virtual IMediaInfo Info { get { return _infoInterface; } }
|
|
|
+ public virtual IMediaControl Control { get { return _controlInterface; } }
|
|
|
+ public virtual IMediaPlayer Player { get { return _playerInterface; } }
|
|
|
+ public virtual ITextureProducer TextureProducer { get { return _textureInterface; } }
|
|
|
+ public virtual IMediaSubtitles Subtitles { get { return _subtitlesInterface; } }
|
|
|
+ public virtual IVideoTracks VideoTracks { get { return _videoTracksInterface; } }
|
|
|
+ public virtual IAudioTracks AudioTracks { get { return _audioTracksInterface; } }
|
|
|
+ public virtual ITextTracks TextTracks { get { return _textTracksInterface; } }
|
|
|
+ public virtual IMediaCache Cache { get { return _cacheInterface; } }
|
|
|
+ public virtual IBufferedDisplay BufferedDisplay { get { return _bufferedDisplayInterface; } }
|
|
|
+
|
|
|
+
|
|
|
+ private bool _isMediaOpened = false;
|
|
|
+ public bool MediaOpened { get { return _isMediaOpened; } }
|
|
|
+ private bool _autoPlayOnStartTriggered = false;
|
|
|
+ private bool _wasPlayingOnPause = false;
|
|
|
+ private Coroutine _renderingCoroutine = null;
|
|
|
+
|
|
|
+
|
|
|
+ private static bool s_GlobalStartup = false;
|
|
|
+ private static bool s_TrialVersion = false;
|
|
|
+
|
|
|
+
|
|
|
+ private MediaPath _queueSubtitlePath;
|
|
|
+ private Coroutine _loadSubtitlesRoutine;
|
|
|
+
|
|
|
+
|
|
|
+ private static Camera _dummyCamera = null;
|
|
|
+ public delegate void ProcessExtractedFrame(Texture2D extractedFrame);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ #if UNITY_EDITOR
|
|
|
+ static MediaPlayer()
|
|
|
+ {
|
|
|
+ SetupEditorPlayPauseSupport();
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ void Awake()
|
|
|
+ {
|
|
|
+ if (_persistent)
|
|
|
+ {
|
|
|
+
|
|
|
+ DontDestroyOnLoad(this.gameObject);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void Initialise()
|
|
|
+ {
|
|
|
+ BaseMediaPlayer mediaPlayer = CreateMediaPlayer();
|
|
|
+ if (mediaPlayer != null)
|
|
|
+ {
|
|
|
+
|
|
|
+ _baseMediaPlayer = mediaPlayer;
|
|
|
+ _controlInterface = mediaPlayer;
|
|
|
+ _textureInterface = mediaPlayer;
|
|
|
+ _infoInterface = mediaPlayer;
|
|
|
+ _playerInterface = mediaPlayer;
|
|
|
+ _subtitlesInterface = mediaPlayer;
|
|
|
+ _videoTracksInterface = mediaPlayer;
|
|
|
+ _audioTracksInterface = mediaPlayer;
|
|
|
+ _textTracksInterface = mediaPlayer;
|
|
|
+ _disposeInterface = mediaPlayer;
|
|
|
+ _cacheInterface = mediaPlayer;
|
|
|
+ _bufferedDisplayInterface = mediaPlayer;
|
|
|
+
|
|
|
+ string nativePluginVersion = mediaPlayer.GetVersion();
|
|
|
+ string expectedNativePluginVersion = mediaPlayer.GetExpectedVersion();
|
|
|
+
|
|
|
+
|
|
|
+ if (!nativePluginVersion.StartsWith(expectedNativePluginVersion))
|
|
|
+ {
|
|
|
+ Debug.LogError("[AVProVideo] Plugin version number " + nativePluginVersion + " doesn't match the expected version number " + expectedNativePluginVersion + ". It looks like the plugin didn't upgrade correctly. To resolve this please restart Unity and try to upgrade the package again.");
|
|
|
+ }
|
|
|
+
|
|
|
+ s_TrialVersion = nativePluginVersion.Contains("-trial");
|
|
|
+
|
|
|
+ if (!s_GlobalStartup)
|
|
|
+ {
|
|
|
+ Helper.LogInfo(string.Format("Initialising AVPro Video v{0} (native plugin v{1}) on {2}/{3} (MT {4}) on {5}", Helper.AVProVideoVersion, nativePluginVersion, SystemInfo.graphicsDeviceName, SystemInfo.graphicsDeviceVersion, SystemInfo.graphicsMultiThreaded, Application.platform));
|
|
|
+
|
|
|
+ #if AVPROVIDEO_BETA_SUPPORT_TIMESCALE
|
|
|
+ Debug.LogWarning("[AVProVideo] TimeScale support used. This could affect performance when changing Time.timeScale or Time.captureFramerate. This feature is useful for supporting video capture system that adjust time scale during capturing.");
|
|
|
+ #endif
|
|
|
+
|
|
|
+ s_GlobalStartup = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void Start()
|
|
|
+ {
|
|
|
+#if UNITY_WEBGL
|
|
|
+ _useResampler = false;
|
|
|
+#endif
|
|
|
+ if (_controlInterface == null)
|
|
|
+ {
|
|
|
+ if (Application.isPlaying)
|
|
|
+ {
|
|
|
+ Initialise();
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ if (_autoOpen)
|
|
|
+ {
|
|
|
+ OpenMedia(_autoPlayOnStart);
|
|
|
+
|
|
|
+ if (_sideloadSubtitles && _subtitlesInterface != null && _subtitlePath != null && !string.IsNullOrEmpty(_subtitlePath.Path))
|
|
|
+ {
|
|
|
+ EnableSubtitles(_subtitlePath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ StartRenderCoroutine();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool OpenMedia(MediaPath path, bool autoPlay = true)
|
|
|
+ {
|
|
|
+ return OpenMedia(path.PathType, path.Path, autoPlay);
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool OpenMedia(MediaPathType pathType, string path, bool autoPlay = true)
|
|
|
+ {
|
|
|
+ _mediaSource = MediaSource.Path;
|
|
|
+ _mediaPath.Path = path;
|
|
|
+ _mediaPath.PathType = pathType;
|
|
|
+
|
|
|
+ return OpenMedia(autoPlay);
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool OpenMedia(MediaReference mediaReference, bool autoPlay = true)
|
|
|
+ {
|
|
|
+ _mediaSource = MediaSource.Reference;
|
|
|
+ _mediaReference = mediaReference;
|
|
|
+
|
|
|
+ return OpenMedia(autoPlay);
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool OpenMedia(bool autoPlay = true)
|
|
|
+ {
|
|
|
+ _autoPlayOnStart = autoPlay;
|
|
|
+
|
|
|
+ if (_controlInterface == null)
|
|
|
+ {
|
|
|
+
|
|
|
+ Initialise();
|
|
|
+ }
|
|
|
+
|
|
|
+ return InternalOpenMedia();
|
|
|
+ }
|
|
|
+
|
|
|
+ private bool InternalOpenMedia()
|
|
|
+ {
|
|
|
+ bool result = false;
|
|
|
+
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ CloseMedia();
|
|
|
+
|
|
|
+ _isMediaOpened = true;
|
|
|
+ _autoPlayOnStartTriggered = !_autoPlayOnStart;
|
|
|
+ _finishedFrameOpenCheck = true;
|
|
|
+ long fileOffset = GetPlatformFileOffset();
|
|
|
+
|
|
|
+ MediaPath mediaPath = null;
|
|
|
+ MediaHints mediaHints = _fallbackMediaHints;
|
|
|
+
|
|
|
+ if (_mediaSource == MediaSource.Reference)
|
|
|
+ {
|
|
|
+ if (_mediaReference != null)
|
|
|
+ {
|
|
|
+ mediaPath = _mediaReference.GetCurrentPlatformMediaReference().MediaPath;
|
|
|
+ mediaHints = _mediaReference.GetCurrentPlatformMediaReference().Hints;
|
|
|
+ if (string.IsNullOrEmpty(mediaPath.Path))
|
|
|
+ {
|
|
|
+ mediaPath = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogError("[AVProVideo] No MediaReference specified", this);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if (_mediaSource == MediaSource.Path)
|
|
|
+ {
|
|
|
+ if (!string.IsNullOrEmpty(_mediaPath.Path))
|
|
|
+ {
|
|
|
+ mediaPath = _mediaPath;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogError("[AVProVideo] No file path specified", this);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (null != mediaPath)
|
|
|
+ {
|
|
|
+ string fullPath = mediaPath.GetResolvedFullPath();
|
|
|
+ string customHttpHeaders = null;
|
|
|
+
|
|
|
+ bool checkForFileExist = true;
|
|
|
+ bool isURL = fullPath.Contains("://");
|
|
|
+ if (isURL)
|
|
|
+ {
|
|
|
+ checkForFileExist = false;
|
|
|
+ customHttpHeaders = GetPlatformHttpHeadersAsString();
|
|
|
+ }
|
|
|
+#if (!UNITY_EDITOR && UNITY_ANDROID)
|
|
|
+ checkForFileExist = false;
|
|
|
+#endif
|
|
|
+ if (checkForFileExist && !System.IO.File.Exists(fullPath))
|
|
|
+ {
|
|
|
+ Debug.LogError("[AVProVideo] File not found: " + fullPath, this);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Helper.LogInfo(string.Format("Opening {0} (offset {1}) with API {2}", fullPath, fileOffset, GetPlatformVideoApiString()), this);
|
|
|
+
|
|
|
+#if UNITY_EDITOR_WIN || (!UNITY_EDITOR && UNITY_STANDALONE_WIN)
|
|
|
+
|
|
|
+
|
|
|
+ if (_optionsWindows.audioOutput == Windows.AudioOutput.FacebookAudio360)
|
|
|
+ {
|
|
|
+ _controlInterface.SetAudioChannelMode(_optionsWindows.audio360ChannelMode);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _controlInterface.SetAudioChannelMode(Audio360ChannelMode.INVALID);
|
|
|
+ }
|
|
|
+#elif (!UNITY_EDITOR && UNITY_WSA_10_0)
|
|
|
+ if (_optionsWindowsUWP.audioOutput == WindowsUWP.AudioOutput.FacebookAudio360)
|
|
|
+ {
|
|
|
+ _controlInterface.SetAudioChannelMode(_optionsWindowsUWP.audio360ChannelMode);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _controlInterface.SetAudioChannelMode(Audio360ChannelMode.INVALID);
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ PlatformOptions options = GetCurrentPlatformOptions();
|
|
|
+ bool startWithHighestBitrate = false;
|
|
|
+ if (options != null)
|
|
|
+ {
|
|
|
+ startWithHighestBitrate = options.StartWithHighestBandwidth();
|
|
|
+ }
|
|
|
+
|
|
|
+ SetLoadOptions();
|
|
|
+
|
|
|
+ if (!_controlInterface.OpenMedia(fullPath, fileOffset, customHttpHeaders, mediaHints, (int)_forceFileFormat, startWithHighestBitrate))
|
|
|
+ {
|
|
|
+ Debug.LogError("[AVProVideo] Failed to open " + fullPath, this);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ SetPlaybackOptions();
|
|
|
+ result = true;
|
|
|
+ StartRenderCoroutine();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogError("[AVProVideo] No file path specified", this);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetLoadOptions()
|
|
|
+ {
|
|
|
+
|
|
|
+ #if !AVPROVIDEO_FORCE_NULL_MEDIAPLAYER
|
|
|
+ #if (UNITY_EDITOR_OSX && UNITY_IOS) || (!UNITY_EDITOR && UNITY_IOS)
|
|
|
+ #elif (UNITY_EDITOR_OSX && UNITY_TVOS) || (!UNITY_EDITOR && UNITY_TVOS)
|
|
|
+ #elif (UNITY_EDITOR_OSX || (!UNITY_EDITOR && UNITY_STANDALONE_OSX))
|
|
|
+ #elif (UNITY_EDITOR_WIN) || (!UNITY_EDITOR && UNITY_STANDALONE_WIN)
|
|
|
+ #elif (!UNITY_EDITOR && UNITY_WSA_10_0)
|
|
|
+ #elif (!UNITY_EDITOR && UNITY_ANDROID)
|
|
|
+ #elif (!UNITY_EDITOR && UNITY_WEBGL)
|
|
|
+ ((WebGLMediaPlayer)_baseMediaPlayer).SetOptions(_optionsWebGL);
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
+
|
|
|
+ PlatformOptions options = GetCurrentPlatformOptions();
|
|
|
+ if (options != null)
|
|
|
+ {
|
|
|
+ _controlInterface.SetKeyServerAuthToken(options.GetKeyServerAuthToken());
|
|
|
+
|
|
|
+ _controlInterface.SetOverrideDecryptionKey(options.GetOverrideDecryptionKey());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void SetPlaybackOptions()
|
|
|
+ {
|
|
|
+
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ _controlInterface.SetLooping(_loop);
|
|
|
+ _controlInterface.SetPlaybackRate(_playbackRate);
|
|
|
+ _controlInterface.SetVolume(_audioVolume);
|
|
|
+ _controlInterface.SetBalance(_audioBalance);
|
|
|
+ #if !UNITY_EDITOR
|
|
|
+ _controlInterface.MuteAudio(_audioMuted);
|
|
|
+ #else
|
|
|
+ _controlInterface.MuteAudio(_audioMuted || UnityEditor.EditorUtility.audioMasterMute);
|
|
|
+ #endif
|
|
|
+ _controlInterface.SetTextureProperties(_textureFilterMode, _textureWrapMode, _textureAnisoLevel);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void CloseMedia()
|
|
|
+ {
|
|
|
+
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ if (_events != null && _isMediaOpened && _events.HasListeners() && IsHandleEvent(MediaPlayerEvent.EventType.Closing))
|
|
|
+ {
|
|
|
+ _events.Invoke(this, MediaPlayerEvent.EventType.Closing, ErrorCode.None);
|
|
|
+ }
|
|
|
+
|
|
|
+ _autoPlayOnStartTriggered = false;
|
|
|
+ _isMediaOpened = false;
|
|
|
+ ResetEvents();
|
|
|
+
|
|
|
+ if (_loadSubtitlesRoutine != null)
|
|
|
+ {
|
|
|
+ StopCoroutine(_loadSubtitlesRoutine);
|
|
|
+ _loadSubtitlesRoutine = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ _controlInterface.CloseMedia();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_resampler != null)
|
|
|
+ {
|
|
|
+ _resampler.Reset();
|
|
|
+ }
|
|
|
+
|
|
|
+ StopRenderCoroutine();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void RewindPrerollPause()
|
|
|
+ {
|
|
|
+ PlatformOptionsWindows.pauseOnPrerollComplete = true;
|
|
|
+ if (BufferedDisplay != null)
|
|
|
+ {
|
|
|
+ BufferedDisplay.SetBufferedDisplayOptions(true);
|
|
|
+ }
|
|
|
+ Rewind(false);
|
|
|
+ Play();
|
|
|
+ }
|
|
|
+
|
|
|
+ public virtual void Play()
|
|
|
+ {
|
|
|
+ if (_controlInterface != null && _controlInterface.CanPlay())
|
|
|
+ {
|
|
|
+ _controlInterface.Play();
|
|
|
+
|
|
|
+
|
|
|
+ _eventFired_ReadyToPlay = true;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+
|
|
|
+ _autoPlayOnStart = true;
|
|
|
+ _autoPlayOnStartTriggered = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public virtual void Pause()
|
|
|
+ {
|
|
|
+ if (_controlInterface != null && _controlInterface.IsPlaying())
|
|
|
+ {
|
|
|
+ _controlInterface.Pause();
|
|
|
+ }
|
|
|
+ _wasPlayingOnPause = false;
|
|
|
+#if AVPROVIDEO_BETA_SUPPORT_TIMESCALE
|
|
|
+ _timeScaleIsControlling = false;
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Stop()
|
|
|
+ {
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ _controlInterface.Stop();
|
|
|
+ }
|
|
|
+#if AVPROVIDEO_BETA_SUPPORT_TIMESCALE
|
|
|
+ _timeScaleIsControlling = false;
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Rewind(bool pause)
|
|
|
+ {
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ if (pause)
|
|
|
+ {
|
|
|
+ Pause();
|
|
|
+ }
|
|
|
+ _controlInterface.Rewind();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void SeekToLiveTime(double offset = 0.0)
|
|
|
+ {
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ double liveTime = _controlInterface.GetBufferedTimes().MaxTime;
|
|
|
+ if (liveTime > 0.0)
|
|
|
+ {
|
|
|
+ _controlInterface.Seek(liveTime - offset);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+#if UNITY_EDITOR && AVPROVIDEO_SUPPORT_LIVEEDITMODE
|
|
|
+ public bool EditorUpdate()
|
|
|
+ {
|
|
|
+ if (_playerInterface != null)
|
|
|
+ {
|
|
|
+ Update();
|
|
|
+ _playerInterface.Render();
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+ protected virtual void Update()
|
|
|
+ {
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+
|
|
|
+ if (_isMediaOpened && _autoPlayOnStart && !_autoPlayOnStartTriggered && _controlInterface.CanPlay())
|
|
|
+ {
|
|
|
+ _autoPlayOnStartTriggered = true;
|
|
|
+ Play();
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Application.isPlaying)
|
|
|
+ {
|
|
|
+ if (_renderingCoroutine == null && _controlInterface.CanPlay())
|
|
|
+ {
|
|
|
+ StartRenderCoroutine();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_subtitlesInterface != null && _queueSubtitlePath != null && !string.IsNullOrEmpty(_queueSubtitlePath.Path))
|
|
|
+ {
|
|
|
+ EnableSubtitles(_queueSubtitlePath);
|
|
|
+ _queueSubtitlePath = null;
|
|
|
+ }
|
|
|
+
|
|
|
+#if AVPROVIDEO_BETA_SUPPORT_TIMESCALE
|
|
|
+ UpdateTimeScale();
|
|
|
+#endif
|
|
|
+
|
|
|
+ UpdateAudioHeadTransform();
|
|
|
+ UpdateAudioFocus();
|
|
|
+
|
|
|
+ _playerInterface.Update();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ UpdateErrors();
|
|
|
+ UpdateEvents();
|
|
|
+
|
|
|
+ _playerInterface.EndUpdate();
|
|
|
+ }
|
|
|
+
|
|
|
+#if UNITY_EDITOR
|
|
|
+ CheckEditorAudioMute();
|
|
|
+#endif
|
|
|
+ }
|
|
|
+
|
|
|
+ private void LateUpdate()
|
|
|
+ {
|
|
|
+ UpdateResampler();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateResampler()
|
|
|
+ {
|
|
|
+#if !UNITY_WEBGL
|
|
|
+ if (_useResampler)
|
|
|
+ {
|
|
|
+ if (_resampler == null)
|
|
|
+ {
|
|
|
+ _resampler = new Resampler(this, gameObject.name, _resampleBufferSize, _resampleMode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+#else
|
|
|
+ _useResampler = false;
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (_resampler != null)
|
|
|
+ {
|
|
|
+ _resampler.Update();
|
|
|
+ _resampler.UpdateTimestamp();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void OnEnable()
|
|
|
+ {
|
|
|
+ if (_controlInterface != null && _wasPlayingOnPause)
|
|
|
+ {
|
|
|
+ _autoPlayOnStart = true;
|
|
|
+ _autoPlayOnStartTriggered = false;
|
|
|
+ _wasPlayingOnPause = false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(_playerInterface != null)
|
|
|
+ {
|
|
|
+ _playerInterface.OnEnable();
|
|
|
+ StartRenderCoroutine();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void OnDisable()
|
|
|
+ {
|
|
|
+ if (_controlInterface != null)
|
|
|
+ {
|
|
|
+ if (_controlInterface.IsPlaying())
|
|
|
+ {
|
|
|
+ Pause();
|
|
|
+
|
|
|
+ Update();
|
|
|
+
|
|
|
+ _wasPlayingOnPause = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ StopRenderCoroutine();
|
|
|
+ }
|
|
|
+
|
|
|
+ protected virtual void OnDestroy()
|
|
|
+ {
|
|
|
+ CloseMedia();
|
|
|
+
|
|
|
+ _baseMediaPlayer = null;
|
|
|
+ _controlInterface = null;
|
|
|
+ _textureInterface = null;
|
|
|
+ _infoInterface = null;
|
|
|
+ _playerInterface = null;
|
|
|
+ _subtitlesInterface = null;
|
|
|
+ _cacheInterface = null;
|
|
|
+ _bufferedDisplayInterface = null;
|
|
|
+ _videoTracksInterface = null;
|
|
|
+ _audioTracksInterface = null;
|
|
|
+ _textTracksInterface = null;
|
|
|
+
|
|
|
+ if (_disposeInterface != null)
|
|
|
+ {
|
|
|
+ _disposeInterface.Dispose();
|
|
|
+ _disposeInterface = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_resampler != null)
|
|
|
+ {
|
|
|
+ _resampler.Release();
|
|
|
+ _resampler = null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public void ForceDispose()
|
|
|
+ {
|
|
|
+ OnDisable();
|
|
|
+ OnDestroy();
|
|
|
+ }
|
|
|
+
|
|
|
+#if UNITY_EDITOR
|
|
|
+ public static void EditorAllPlayersDispose()
|
|
|
+ {
|
|
|
+ AllPlayersDispose();
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ private static void AllPlayersDispose()
|
|
|
+ {
|
|
|
+
|
|
|
+ MediaPlayer[] players = Resources.FindObjectsOfTypeAll<MediaPlayer>();
|
|
|
+ if (players != null && players.Length > 0)
|
|
|
+ {
|
|
|
+ for (int i = 0; i < players.Length; i++)
|
|
|
+ {
|
|
|
+ players[i].ForceDispose();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void OnApplicationQuit()
|
|
|
+ {
|
|
|
+ if (s_GlobalStartup)
|
|
|
+ {
|
|
|
+ Helper.LogInfo("Shutdown");
|
|
|
+
|
|
|
+ AllPlayersDispose();
|
|
|
+
|
|
|
+#if UNITY_EDITOR
|
|
|
+ #if UNITY_EDITOR_WIN
|
|
|
+ WindowsMediaPlayer.DeinitPlatform();
|
|
|
+ WindowsRtMediaPlayer.DeinitPlatform();
|
|
|
+ #endif
|
|
|
+#else
|
|
|
+ #if (UNITY_STANDALONE_WIN)
|
|
|
+ WindowsMediaPlayer.DeinitPlatform();
|
|
|
+ WindowsRtMediaPlayer.DeinitPlatform();
|
|
|
+ #elif (UNITY_ANDROID)
|
|
|
+ AndroidMediaPlayer.DeinitPlatform();
|
|
|
+ #endif
|
|
|
+#endif
|
|
|
+ s_GlobalStartup = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+#region Rendering Coroutine
|
|
|
+
|
|
|
+ private void StartRenderCoroutine()
|
|
|
+ {
|
|
|
+ if (_renderingCoroutine == null)
|
|
|
+ {
|
|
|
+
|
|
|
+ _renderingCoroutine = StartCoroutine(FinalRenderCapture());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void StopRenderCoroutine()
|
|
|
+ {
|
|
|
+ if (_renderingCoroutine != null)
|
|
|
+ {
|
|
|
+ StopCoroutine(_renderingCoroutine);
|
|
|
+ _renderingCoroutine = null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private IEnumerator FinalRenderCapture()
|
|
|
+ {
|
|
|
+
|
|
|
+ YieldInstruction wait = new WaitForEndOfFrame();
|
|
|
+ while (Application.isPlaying)
|
|
|
+ {
|
|
|
+
|
|
|
+ yield return wait;
|
|
|
+
|
|
|
+ if (this.enabled)
|
|
|
+ {
|
|
|
+ if (_playerInterface != null)
|
|
|
+ {
|
|
|
+ _playerInterface.Render();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endregion // Rendering Coroutine
|
|
|
+
|
|
|
+#region Platform and Path
|
|
|
+ public static Platform GetPlatform()
|
|
|
+ {
|
|
|
+ Platform result = Platform.Unknown;
|
|
|
+
|
|
|
+
|
|
|
+#if UNITY_EDITOR
|
|
|
+#if (UNITY_EDITOR_OSX && UNITY_EDITOR_64)
|
|
|
+ result = Platform.MacOSX;
|
|
|
+#elif UNITY_EDITOR_WIN
|
|
|
+ result = Platform.Windows;
|
|
|
+#endif
|
|
|
+#else
|
|
|
+
|
|
|
+#if (UNITY_STANDALONE_WIN)
|
|
|
+ result = Platform.Windows;
|
|
|
+#elif (UNITY_STANDALONE_OSX)
|
|
|
+ result = Platform.MacOSX;
|
|
|
+#elif (UNITY_IPHONE || UNITY_IOS)
|
|
|
+ result = Platform.iOS;
|
|
|
+#elif (UNITY_TVOS)
|
|
|
+ result = Platform.tvOS;
|
|
|
+#elif (UNITY_ANDROID)
|
|
|
+ result = Platform.Android;
|
|
|
+#elif (UNITY_WSA_10_0)
|
|
|
+ result = Platform.WindowsUWP;
|
|
|
+#elif (UNITY_WEBGL)
|
|
|
+ result = Platform.WebGL;
|
|
|
+#endif
|
|
|
+
|
|
|
+#endif
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public PlatformOptions GetCurrentPlatformOptions()
|
|
|
+ {
|
|
|
+ PlatformOptions result = null;
|
|
|
+
|
|
|
+#if UNITY_EDITOR
|
|
|
+#if (UNITY_EDITOR_OSX && UNITY_EDITOR_64)
|
|
|
+ result = _optionsMacOSX;
|
|
|
+#elif UNITY_EDITOR_WIN
|
|
|
+ result = _optionsWindows;
|
|
|
+#endif
|
|
|
+#else
|
|
|
+
|
|
|
+
|
|
|
+#if (UNITY_STANDALONE_WIN)
|
|
|
+ result = _optionsWindows;
|
|
|
+#elif (UNITY_STANDALONE_OSX)
|
|
|
+ result = _optionsMacOSX;
|
|
|
+#elif (UNITY_IPHONE || UNITY_IOS)
|
|
|
+ result = _optionsIOS;
|
|
|
+#elif (UNITY_TVOS)
|
|
|
+ result = _optionsTVOS;
|
|
|
+#elif (UNITY_ANDROID)
|
|
|
+ result = _optionsAndroid;
|
|
|
+#elif (UNITY_WSA_10_0)
|
|
|
+ result = _optionsWindowsUWP;
|
|
|
+#elif (UNITY_WEBGL)
|
|
|
+ result = _optionsWebGL;
|
|
|
+#endif
|
|
|
+
|
|
|
+#endif
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+#if UNITY_EDITOR
|
|
|
+ public PlatformOptions GetPlatformOptions(Platform platform)
|
|
|
+ {
|
|
|
+ PlatformOptions result = null;
|
|
|
+
|
|
|
+ switch (platform)
|
|
|
+ {
|
|
|
+ case Platform.Windows:
|
|
|
+ result = _optionsWindows;
|
|
|
+ break;
|
|
|
+ case Platform.MacOSX:
|
|
|
+ result = _optionsMacOSX;
|
|
|
+ break;
|
|
|
+ case Platform.Android:
|
|
|
+ result = _optionsAndroid;
|
|
|
+ break;
|
|
|
+ case Platform.iOS:
|
|
|
+ result = _optionsIOS;
|
|
|
+ break;
|
|
|
+ case Platform.tvOS:
|
|
|
+ result = _optionsTVOS;
|
|
|
+ break;
|
|
|
+ case Platform.WindowsUWP:
|
|
|
+ result = _optionsWindowsUWP;
|
|
|
+ break;
|
|
|
+ case Platform.WebGL:
|
|
|
+ result = _optionsWebGL;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static string GetPlatformOptionsVariable(Platform platform)
|
|
|
+ {
|
|
|
+ string result = string.Empty;
|
|
|
+
|
|
|
+ switch (platform)
|
|
|
+ {
|
|
|
+ case Platform.Windows:
|
|
|
+ result = "_optionsWindows";
|
|
|
+ break;
|
|
|
+ case Platform.MacOSX:
|
|
|
+ result = "_optionsMacOSX";
|
|
|
+ break;
|
|
|
+ case Platform.iOS:
|
|
|
+ result = "_optionsIOS";
|
|
|
+ break;
|
|
|
+ case Platform.tvOS:
|
|
|
+ result = "_optionsTVOS";
|
|
|
+ break;
|
|
|
+ case Platform.Android:
|
|
|
+ result = "_optionsAndroid";
|
|
|
+ break;
|
|
|
+ case Platform.WindowsUWP:
|
|
|
+ result = "_optionsWindowsUWP";
|
|
|
+ break;
|
|
|
+ case Platform.WebGL:
|
|
|
+ result = "_optionsWebGL";
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+#endif
|
|
|
+
|
|
|
+ private string GetPlatformVideoApiString()
|
|
|
+ {
|
|
|
+ string result = string.Empty;
|
|
|
+#if UNITY_EDITOR
|
|
|
+ #if UNITY_EDITOR_OSX
|
|
|
+ #elif UNITY_EDITOR_WIN
|
|
|
+ result = _optionsWindows.videoApi.ToString();
|
|
|
+ #elif UNITY_EDITOR_LINUX
|
|
|
+ #endif
|
|
|
+#else
|
|
|
+ #if UNITY_STANDALONE_WIN
|
|
|
+ result = _optionsWindows.videoApi.ToString();
|
|
|
+ #elif UNITY_WSA_10_0
|
|
|
+ result = _optionsWindowsUWP.videoApi.ToString();
|
|
|
+ #elif UNITY_ANDROID
|
|
|
+ result = _optionsAndroid.videoApi.ToString();
|
|
|
+ #endif
|
|
|
+#endif
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private long GetPlatformFileOffset()
|
|
|
+ {
|
|
|
+ long result = 0;
|
|
|
+#if UNITY_EDITOR
|
|
|
+ #if UNITY_EDITOR_OSX
|
|
|
+ #elif UNITY_EDITOR_WIN
|
|
|
+ #elif UNITY_EDITOR_LINUX
|
|
|
+ #endif
|
|
|
+#else
|
|
|
+ #if UNITY_ANDROID
|
|
|
+ result = _optionsAndroid.fileOffset;
|
|
|
+ #endif
|
|
|
+#endif
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private string GetPlatformHttpHeadersAsString()
|
|
|
+ {
|
|
|
+ string result = null;
|
|
|
+
|
|
|
+#if UNITY_EDITOR
|
|
|
+ #if UNITY_EDITOR_OSX
|
|
|
+ result = _optionsMacOSX.httpHeaders.ToValidatedString();
|
|
|
+ #elif UNITY_EDITOR_WIN
|
|
|
+ result = _optionsWindows.httpHeaders.ToValidatedString();
|
|
|
+ #elif UNITY_EDITOR_LINUX
|
|
|
+ #endif
|
|
|
+#else
|
|
|
+ #if UNITY_STANDALONE_OSX
|
|
|
+ result = _optionsMacOSX.httpHeaders.ToValidatedString();
|
|
|
+ #elif UNITY_STANDALONE_WIN
|
|
|
+ result = _optionsWindows.httpHeaders.ToValidatedString();
|
|
|
+ #elif UNITY_WSA_10_0
|
|
|
+ result = _optionsWindowsUWP.httpHeaders.ToValidatedString();
|
|
|
+ #elif UNITY_IOS || UNITY_IPHONE
|
|
|
+ result = _optionsIOS.httpHeaders.ToValidatedString();
|
|
|
+ #elif UNITY_TVOS
|
|
|
+ result = _optionsTVOS.httpHeaders.ToValidatedString();
|
|
|
+ #elif UNITY_ANDROID
|
|
|
+ result = _optionsAndroid.httpHeaders.ToValidatedString();
|
|
|
+ #elif UNITY_WEBGL
|
|
|
+ #endif
|
|
|
+#endif
|
|
|
+
|
|
|
+ if (!string.IsNullOrEmpty(result))
|
|
|
+ {
|
|
|
+ result = result.Trim();
|
|
|
+ }
|
|
|
+
|
|
|
+ string globalHeaders = _httpHeaders.ToValidatedString();
|
|
|
+ if (!string.IsNullOrEmpty(globalHeaders))
|
|
|
+ {
|
|
|
+ result += globalHeaders;
|
|
|
+ result = result.Trim();
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private string GetResolvedFilePath(string filePath, MediaPathType fileLocation)
|
|
|
+ {
|
|
|
+ string result = string.Empty;
|
|
|
+
|
|
|
+ result = Helper.GetFilePath(filePath, fileLocation);
|
|
|
+
|
|
|
+ #if (UNITY_EDITOR_WIN || (!UNITY_EDITOR && UNITY_STANDALONE_WIN))
|
|
|
+ if (result.Length > 200 && !result.Contains("://"))
|
|
|
+ {
|
|
|
+ result = Helper.ConvertLongPathToShortDOS83Path(result);
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+#endregion // Platform and Path
|
|
|
+
|
|
|
+#region Create MediaPlayers
|
|
|
+ #if (UNITY_EDITOR_WIN) || (!UNITY_EDITOR && UNITY_STANDALONE_WIN)
|
|
|
+ private static BaseMediaPlayer CreateMediaPlayer(OptionsWindows options)
|
|
|
+ {
|
|
|
+ BaseMediaPlayer result = null;
|
|
|
+ if (options.videoApi == Windows.VideoApi.WinRT)
|
|
|
+ {
|
|
|
+ if (WindowsRtMediaPlayer.InitialisePlatform())
|
|
|
+ {
|
|
|
+ result = new WindowsRtMediaPlayer(options);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning(string.Format("[AVProVideo] Failed to initialise WinRT API - platform {0} may not support it. Trying another video API...", SystemInfo.operatingSystem));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (result == null)
|
|
|
+ {
|
|
|
+ if (WindowsMediaPlayer.InitialisePlatform())
|
|
|
+ {
|
|
|
+ result = new WindowsMediaPlayer(options);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #if (!UNITY_EDITOR && UNITY_WSA_10_0)
|
|
|
+ private static BaseMediaPlayer CreateMediaPlayer(OptionsWindowsUWP options)
|
|
|
+ {
|
|
|
+ BaseMediaPlayer result = null;
|
|
|
+ if (options.videoApi == WindowsUWP.VideoApi.WinRT)
|
|
|
+ {
|
|
|
+ if (WindowsRtMediaPlayer.InitialisePlatform())
|
|
|
+ {
|
|
|
+ result = new WindowsRtMediaPlayer(options);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ Debug.LogWarning(string.Format("[AVProVideo] Failed to initialise WinRT API - platform {0} may not support it. Trying another video API...", SystemInfo.operatingSystem));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (result == null)
|
|
|
+ {
|
|
|
+ if (WindowsMediaPlayer.InitialisePlatform())
|
|
|
+ {
|
|
|
+ result = new WindowsMediaPlayer(options);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #if (!UNITY_EDITOR && UNITY_ANDROID)
|
|
|
+ private static BaseMediaPlayer CreateMediaPlayer(OptionsAndroid options)
|
|
|
+ {
|
|
|
+ BaseMediaPlayer result = null;
|
|
|
+
|
|
|
+ if (AndroidMediaPlayer.InitialisePlatform())
|
|
|
+ {
|
|
|
+ result = new AndroidMediaPlayer(options);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #if (UNITY_EDITOR_OSX) || (!UNITY_EDITOR && (UNITY_STANDALONE_OSX || UNITY_IPHONE || UNITY_IOS || UNITY_TVOS))
|
|
|
+ private static BaseMediaPlayer CreateMediaPlayer(OptionsApple options)
|
|
|
+ {
|
|
|
+ AppleMediaPlayer mediaPlayer = new AppleMediaPlayer(options);
|
|
|
+ return mediaPlayer;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ #if (!UNITY_EDITOR && UNITY_WEBGL)
|
|
|
+ private static BaseMediaPlayer CreateMediaPlayer(OptionsWebGL options)
|
|
|
+ {
|
|
|
+ BaseMediaPlayer result = null;
|
|
|
+ if (WebGLMediaPlayer.InitialisePlatform())
|
|
|
+ {
|
|
|
+ result = new WebGLMediaPlayer(options);
|
|
|
+ }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+
|
|
|
+ private static BaseMediaPlayer CreateMediaPlayerNull()
|
|
|
+ {
|
|
|
+ return new NullMediaPlayer();
|
|
|
+ }
|
|
|
+
|
|
|
+ public virtual BaseMediaPlayer CreateMediaPlayer()
|
|
|
+ {
|
|
|
+ BaseMediaPlayer mediaPlayer = null;
|
|
|
+
|
|
|
+ #if !AVPROVIDEO_FORCE_NULL_MEDIAPLAYER
|
|
|
+ #if (UNITY_EDITOR_OSX && UNITY_IOS) || (!UNITY_EDITOR && UNITY_IOS)
|
|
|
+ mediaPlayer = CreateMediaPlayer(_optionsIOS);
|
|
|
+ #elif (UNITY_EDITOR_OSX && UNITY_TVOS) || (!UNITY_EDITOR && UNITY_TVOS)
|
|
|
+ mediaPlayer = CreateMediaPlayer(_optionsTVOS);
|
|
|
+ #elif (UNITY_EDITOR_OSX || (!UNITY_EDITOR && UNITY_STANDALONE_OSX))
|
|
|
+ mediaPlayer = CreateMediaPlayer(_optionsMacOSX);
|
|
|
+ #elif (UNITY_EDITOR_WIN) || (!UNITY_EDITOR && UNITY_STANDALONE_WIN)
|
|
|
+ mediaPlayer = CreateMediaPlayer(_optionsWindows);
|
|
|
+ #elif (!UNITY_EDITOR && UNITY_WSA_10_0)
|
|
|
+ mediaPlayer = CreateMediaPlayer(_optionsWindowsUWP);
|
|
|
+ #elif (!UNITY_EDITOR && UNITY_ANDROID)
|
|
|
+ mediaPlayer = CreateMediaPlayer(_optionsAndroid);
|
|
|
+ #elif (!UNITY_EDITOR && UNITY_WEBGL)
|
|
|
+ mediaPlayer = CreateMediaPlayer(_optionsWebGL);
|
|
|
+ #endif
|
|
|
+ #endif
|
|
|
+
|
|
|
+ if (mediaPlayer == null)
|
|
|
+ {
|
|
|
+ Debug.LogError(string.Format("[AVProVideo] Not supported on this platform {0} {1} {2} {3}. Using null media player!", Application.platform, SystemInfo.deviceModel, SystemInfo.processorType, SystemInfo.operatingSystem));
|
|
|
+ mediaPlayer = CreateMediaPlayerNull();
|
|
|
+ }
|
|
|
+
|
|
|
+ return mediaPlayer;
|
|
|
+ }
|
|
|
+#endregion // Create MediaPlayers
|
|
|
+
|
|
|
+ private void UpdateAudioFocus()
|
|
|
+ {
|
|
|
+
|
|
|
+ _controlInterface.SetAudioFocusEnabled(_audioFocusEnabled);
|
|
|
+ _controlInterface.SetAudioFocusProperties(_audioFocusOffLevelDB, _audioFocusWidthDegrees);
|
|
|
+ _controlInterface.SetAudioFocusRotation(_audioFocusTransform == null ? Quaternion.identity : _audioFocusTransform.rotation);
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateAudioHeadTransform()
|
|
|
+ {
|
|
|
+ if (_audioHeadTransform != null)
|
|
|
+ {
|
|
|
+ _controlInterface.SetAudioHeadRotation(_audioHeadTransform.rotation);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _controlInterface.ResetAudioHeadRotation();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void UpdateErrors()
|
|
|
+ {
|
|
|
+ ErrorCode errorCode = _controlInterface.GetLastError();
|
|
|
+ if (ErrorCode.None != errorCode)
|
|
|
+ {
|
|
|
+ Debug.LogError("[AVProVideo] Error: " + Helper.GetErrorMessage(errorCode));
|
|
|
+
|
|
|
+
|
|
|
+ if (ErrorCode.LoadFailed == errorCode)
|
|
|
+ {
|
|
|
+ #if !UNITY_EDITOR && UNITY_ANDROID
|
|
|
+
|
|
|
+ if (_mediaPath.Path.ToLower().Contains("http://"))
|
|
|
+ {
|
|
|
+ Debug.LogError("Android 8 and above require HTTPS by default, change to HTTPS or enable ClearText in the AndroidManifest.xml");
|
|
|
+ }
|
|
|
+ #endif
|
|
|
+ }
|
|
|
+
|
|
|
+ if (_events != null && _events.HasListeners() && IsHandleEvent(MediaPlayerEvent.EventType.Error))
|
|
|
+ {
|
|
|
+ _events.Invoke(this, MediaPlayerEvent.EventType.Error, errorCode);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool IsUsingAndroidOESPath()
|
|
|
+ {
|
|
|
+
|
|
|
+ bool result = (PlatformOptionsAndroid.useFastOesPath && !s_TrialVersion);
|
|
|
+ #if (UNITY_EDITOR || !UNITY_ANDROID)
|
|
|
+ result = false;
|
|
|
+ #endif
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+#region Save Frame To PNG
|
|
|
+#if UNITY_EDITOR || (!UNITY_EDITOR && (UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX))
|
|
|
+ [ContextMenu("Save Frame To PNG")]
|
|
|
+ public void SaveFrameToPng()
|
|
|
+ {
|
|
|
+ Texture2D frame = ExtractFrame(null);
|
|
|
+ if (frame != null)
|
|
|
+ {
|
|
|
+ byte[] imageBytes = frame.EncodeToPNG();
|
|
|
+ if (imageBytes != null)
|
|
|
+ {
|
|
|
+ string timecode = Mathf.FloorToInt((float)(Control.GetCurrentTime() * 1000.0)).ToString("D8");
|
|
|
+ System.IO.File.WriteAllBytes("frame-" + timecode + ".png", imageBytes);
|
|
|
+ }
|
|
|
+
|
|
|
+ Destroy(frame);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ [ContextMenu("Save Frame To EXR")]
|
|
|
+ public void SaveFrameToExr()
|
|
|
+ {
|
|
|
+ Texture frame = (Texture)TextureProducer.GetTexture(0);
|
|
|
+ if (frame != null)
|
|
|
+ {
|
|
|
+ RenderTexture rt = new RenderTexture(frame.width, frame.height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
|
|
|
+ rt.Create();
|
|
|
+ Graphics.Blit(frame, rt);
|
|
|
+ Texture2D frameRead = new Texture2D(frame.width, frame.height, TextureFormat.RGBAFloat, false, true);
|
|
|
+ RenderTexture.active = rt;
|
|
|
+ frameRead.ReadPixels(new Rect(0f, 0f, frame.width, frame.height), 0, 0, false);
|
|
|
+ frameRead.Apply(false, false);
|
|
|
+ RenderTexture.active = null;
|
|
|
+ byte[] imageBytes = frameRead.EncodeToEXR();
|
|
|
+ if (imageBytes != null)
|
|
|
+ {
|
|
|
+ string timecode = Mathf.FloorToInt((float)(Control.GetCurrentTime() * 1000.0)).ToString("D8");
|
|
|
+ System.IO.File.WriteAllBytes("frame-" + timecode + ".exr", imageBytes);
|
|
|
+ }
|
|
|
+
|
|
|
+ Destroy(frame);
|
|
|
+ Texture2D.Destroy(frameRead);
|
|
|
+ RenderTexture.Destroy(rt);
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+#endregion // Save Frame To PNG
|
|
|
+ }
|
|
|
+}
|