using System; using System.IO; using UnityEngine; using UnityEngine.Events; namespace RenderHeads.Media.AVProVideo.Demos { public class FrameExtract : MonoBehaviour { private void Start() { this._mediaPlayer.Events.AddListener(new UnityAction(this.OnMediaPlayerEvent)); this._displaySheet = RenderTexture.GetTemporary(Screen.width, Screen.height, 0); this._displaySheet.useMipMap = false; this._displaySheet.autoGenerateMips = false; this._displaySheet.antiAliasing = 1; this._displaySheet.Create(); RenderTexture.active = this._displaySheet; GL.Clear(false, true, Color.black, 0f); RenderTexture.active = null; } public void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode) { if (et != MediaPlayerEvent.EventType.MetaDataReady) { if (et == MediaPlayerEvent.EventType.FirstFrameReady) { this.OnNewMediaReady(); } } else { mp.Play(); mp.Pause(); } } private void OnNewMediaReady() { IMediaInfo info = this._mediaPlayer.Info; if (this._texture != null) { UnityEngine.Object.Destroy(this._texture); this._texture = null; } this._texture = new Texture2D(info.GetVideoWidth(), info.GetVideoHeight(), TextureFormat.ARGB32, false); this._timeStepSeconds = this._mediaPlayer.Info.GetDurationMs() / 1000f / 8f; this._filenamePrefix = Path.GetFileName(this._mediaPlayer.m_VideoPath); } private void OnDestroy() { if (this._texture != null) { UnityEngine.Object.Destroy(this._texture); this._texture = null; } if (this._displaySheet != null) { RenderTexture.ReleaseTemporary(this._displaySheet); this._displaySheet = null; } } private void Update() { if (this._texture != null && this._frameIndex >= 0 && this._frameIndex < 8) { this.ExtractNextFrame(); this._frameIndex++; } } private void ExtractNextFrame() { float timeSeconds = (float)this._frameIndex * this._timeStepSeconds; this._texture = this._mediaPlayer.ExtractFrame(this._texture, timeSeconds, this._accurateSeek, this._timeoutMs); if (this._saveToJPG) { string text = string.Concat(new object[] { this._filenamePrefix, "-", this._frameIndex, ".jpg" }); Debug.Log("Writing frame to file: " + text); File.WriteAllBytes(text, this._texture.EncodeToJPG()); } GL.PushMatrix(); RenderTexture.active = this._displaySheet; GL.LoadPixelMatrix(0f, (float)this._displaySheet.width, (float)this._displaySheet.height, 0f); Rect sourceRect = new Rect(0f, 0f, 1f, 1f); float num = 8f; float num2 = (float)this._displaySheet.width / 8f - num; float num3 = num2 / ((float)this._texture.width / (float)this._texture.height); float x = (num2 + num) * (float)this._frameIndex; Rect screenRect = new Rect(x, (float)this._displaySheet.height / 2f - num3 / 2f, num2, num3); Graphics.DrawTexture(screenRect, this._texture, sourceRect, 0, 0, 0, 0); RenderTexture.active = null; GL.PopMatrix(); GL.InvalidateState(); } private void OnGUI() { GUI.skin = this._skin; if (this._displaySheet != null) { GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), this._displaySheet, ScaleMode.ScaleToFit, false); } float num = 4f * ((float)Screen.height / 1080f); GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f)); GUILayout.Space(16f); GUILayout.BeginHorizontal(new GUILayoutOption[] { GUILayout.ExpandWidth(true), GUILayout.Width((float)Screen.width / num) }); GUILayout.FlexibleSpace(); if (GUILayout.Button("Start Extracting Frames", new GUILayoutOption[0])) { this._frameIndex = 0; RenderTexture.active = this._displaySheet; GL.Clear(false, true, Color.black, 0f); RenderTexture.active = null; } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); } private const int NumFrames = 8; public MediaPlayer _mediaPlayer; public bool _accurateSeek; public int _timeoutMs = 250; public GUISkin _skin; public bool _saveToJPG; private string _filenamePrefix; private float _timeStepSeconds; private int _frameIndex = -1; private Texture2D _texture; private RenderTexture _displaySheet; } }