FrameExtract.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. using System;
  2. using System.IO;
  3. using UnityEngine;
  4. using UnityEngine.Events;
  5. namespace RenderHeads.Media.AVProVideo.Demos
  6. {
  7. public class FrameExtract : MonoBehaviour
  8. {
  9. private void Start()
  10. {
  11. this._mediaPlayer.Events.AddListener(new UnityAction<MediaPlayer, MediaPlayerEvent.EventType, ErrorCode>(this.OnMediaPlayerEvent));
  12. this._displaySheet = RenderTexture.GetTemporary(Screen.width, Screen.height, 0);
  13. this._displaySheet.useMipMap = false;
  14. this._displaySheet.autoGenerateMips = false;
  15. this._displaySheet.antiAliasing = 1;
  16. this._displaySheet.Create();
  17. RenderTexture.active = this._displaySheet;
  18. GL.Clear(false, true, Color.black, 0f);
  19. RenderTexture.active = null;
  20. }
  21. public void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
  22. {
  23. if (et != MediaPlayerEvent.EventType.MetaDataReady)
  24. {
  25. if (et == MediaPlayerEvent.EventType.FirstFrameReady)
  26. {
  27. this.OnNewMediaReady();
  28. }
  29. }
  30. else
  31. {
  32. mp.Play();
  33. mp.Pause();
  34. }
  35. }
  36. private void OnNewMediaReady()
  37. {
  38. IMediaInfo info = this._mediaPlayer.Info;
  39. if (this._texture != null)
  40. {
  41. UnityEngine.Object.Destroy(this._texture);
  42. this._texture = null;
  43. }
  44. this._texture = new Texture2D(info.GetVideoWidth(), info.GetVideoHeight(), TextureFormat.ARGB32, false);
  45. this._timeStepSeconds = this._mediaPlayer.Info.GetDurationMs() / 1000f / 8f;
  46. this._filenamePrefix = Path.GetFileName(this._mediaPlayer.m_VideoPath);
  47. }
  48. private void OnDestroy()
  49. {
  50. if (this._texture != null)
  51. {
  52. UnityEngine.Object.Destroy(this._texture);
  53. this._texture = null;
  54. }
  55. if (this._displaySheet != null)
  56. {
  57. RenderTexture.ReleaseTemporary(this._displaySheet);
  58. this._displaySheet = null;
  59. }
  60. }
  61. private void Update()
  62. {
  63. if (this._texture != null && this._frameIndex >= 0 && this._frameIndex < 8)
  64. {
  65. this.ExtractNextFrame();
  66. this._frameIndex++;
  67. }
  68. }
  69. private void ExtractNextFrame()
  70. {
  71. float timeSeconds = (float)this._frameIndex * this._timeStepSeconds;
  72. this._texture = this._mediaPlayer.ExtractFrame(this._texture, timeSeconds, this._accurateSeek, this._timeoutMs);
  73. if (this._saveToJPG)
  74. {
  75. string text = string.Concat(new object[]
  76. {
  77. this._filenamePrefix,
  78. "-",
  79. this._frameIndex,
  80. ".jpg"
  81. });
  82. Debug.Log("Writing frame to file: " + text);
  83. File.WriteAllBytes(text, this._texture.EncodeToJPG());
  84. }
  85. GL.PushMatrix();
  86. RenderTexture.active = this._displaySheet;
  87. GL.LoadPixelMatrix(0f, (float)this._displaySheet.width, (float)this._displaySheet.height, 0f);
  88. Rect sourceRect = new Rect(0f, 0f, 1f, 1f);
  89. float num = 8f;
  90. float num2 = (float)this._displaySheet.width / 8f - num;
  91. float num3 = num2 / ((float)this._texture.width / (float)this._texture.height);
  92. float x = (num2 + num) * (float)this._frameIndex;
  93. Rect screenRect = new Rect(x, (float)this._displaySheet.height / 2f - num3 / 2f, num2, num3);
  94. Graphics.DrawTexture(screenRect, this._texture, sourceRect, 0, 0, 0, 0);
  95. RenderTexture.active = null;
  96. GL.PopMatrix();
  97. GL.InvalidateState();
  98. }
  99. private void OnGUI()
  100. {
  101. GUI.skin = this._skin;
  102. if (this._displaySheet != null)
  103. {
  104. GUI.DrawTexture(new Rect(0f, 0f, (float)Screen.width, (float)Screen.height), this._displaySheet, ScaleMode.ScaleToFit, false);
  105. }
  106. float num = 4f * ((float)Screen.height / 1080f);
  107. GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f));
  108. GUILayout.Space(16f);
  109. GUILayout.BeginHorizontal(new GUILayoutOption[]
  110. {
  111. GUILayout.ExpandWidth(true),
  112. GUILayout.Width((float)Screen.width / num)
  113. });
  114. GUILayout.FlexibleSpace();
  115. if (GUILayout.Button("Start Extracting Frames", new GUILayoutOption[0]))
  116. {
  117. this._frameIndex = 0;
  118. RenderTexture.active = this._displaySheet;
  119. GL.Clear(false, true, Color.black, 0f);
  120. RenderTexture.active = null;
  121. }
  122. GUILayout.FlexibleSpace();
  123. GUILayout.EndHorizontal();
  124. }
  125. private const int NumFrames = 8;
  126. public MediaPlayer _mediaPlayer;
  127. public bool _accurateSeek;
  128. public int _timeoutMs = 250;
  129. public GUISkin _skin;
  130. public bool _saveToJPG;
  131. private string _filenamePrefix;
  132. private float _timeStepSeconds;
  133. private int _frameIndex = -1;
  134. private Texture2D _texture;
  135. private RenderTexture _displaySheet;
  136. }
  137. }