ShanxiKnowledgeBase/SXElectricalInspection/Assets/AVIDEO/AVideo/AVProVideo/Demos/Scripts/FrameExtract.cs

201 lines
5.6 KiB
C#

#if !UNITY_WEBPLAYER
#if UNITY_STANDALONE_WIN || UNITY_STANDALONE_OSX || UNITY_EDITOR
#define AVPRO_FILESYSTEM_SUPPORT
#endif
#endif
using UnityEngine;
using System.Collections;
//-----------------------------------------------------------------------------
// Copyright 2015-2018 RenderHeads Ltd. All rights reserverd.
//-----------------------------------------------------------------------------
namespace RenderHeads.Media.AVProVideo.Demos
{
/// <summary>
/// A demo that shows how to extract a series of frames from the video,
/// copy them into textures, and then save them to disk as images
/// </summary>
public class FrameExtract : MonoBehaviour
{
private const int NumFrames = 8;
public MediaPlayer _mediaPlayer;
public bool _accurateSeek = false;
public int _timeoutMs = 250;
public GUISkin _skin;
public bool _asyncExtract = false;
#if AVPRO_FILESYSTEM_SUPPORT
public bool _saveToJPG = false;
private string _filenamePrefix;
#endif
private float _timeStepSeconds;
private int _frameIndex = -1;
private Texture2D _texture;
private RenderTexture _displaySheet;
void Start()
{
_mediaPlayer.Events.AddListener(OnMediaPlayerEvent);
// Create a texture to draw the thumbnails on
_displaySheet = RenderTexture.GetTemporary(Screen.width, Screen.height, 0);
_displaySheet.useMipMap = false;
#if UNITY_5_5_OR_NEWER
_displaySheet.autoGenerateMips = false;
#else
_displaySheet.generateMips = false;
#endif
_displaySheet.antiAliasing = 1;
_displaySheet.Create();
// Clear the texture
RenderTexture.active = _displaySheet;
GL.Clear(false, true, Color.black, 0f);
RenderTexture.active = null;
}
public void OnMediaPlayerEvent(MediaPlayer mp, MediaPlayerEvent.EventType et, ErrorCode errorCode)
{
switch (et)
{
case MediaPlayerEvent.EventType.MetaDataReady:
// Android platform doesn't display its first frame until poked
mp.Play();
mp.Pause();
break;
case MediaPlayerEvent.EventType.FirstFrameReady:
OnNewMediaReady();
break;
}
}
private void OnNewMediaReady()
{
IMediaInfo info = _mediaPlayer.Info;
// Create a texture the same resolution as our video
if (_texture != null)
{
Texture2D.Destroy(_texture);
_texture = null;
}
int textureWidth = info.GetVideoWidth();
int textureHeight = info.GetVideoHeight();
#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX || UNITY_IPHONE || UNITY_IOS || UNITY_TVOS
Orientation ori = Helper.GetOrientation(_mediaPlayer.Info.GetTextureTransform());
if (ori == Orientation.Portrait || ori == Orientation.PortraitFlipped)
{
textureWidth = info.GetVideoHeight();
textureHeight = info.GetVideoWidth();
}
#endif
_texture = new Texture2D(textureWidth, textureHeight, TextureFormat.ARGB32, false);
_timeStepSeconds = (_mediaPlayer.Info.GetDurationMs() / 1000f) / (float)NumFrames;
#if AVPRO_FILESYSTEM_SUPPORT
_filenamePrefix = System.IO.Path.GetFileName(_mediaPlayer.m_VideoPath);
#endif
}
void OnDestroy()
{
if (_texture != null)
{
Texture2D.Destroy(_texture);
_texture = null;
}
if (_displaySheet != null)
{
RenderTexture.ReleaseTemporary(_displaySheet);
_displaySheet = null;
}
}
void Update()
{
if (_texture != null && _frameIndex >=0 && _frameIndex < NumFrames)
{
ExtractNextFrame();
_frameIndex++;
}
}
private void ProcessExtractedFrame(Texture2D texture)
{
#if AVPRO_FILESYSTEM_SUPPORT
// Save frame to JPG
if (_saveToJPG)
{
string filePath = _filenamePrefix + "-" + _frameIndex + ".jpg";
Debug.Log("Writing frame to file: " + filePath);
System.IO.File.WriteAllBytes(filePath, texture.EncodeToJPG());
}
#endif
// Draw frame to the thumbnail sheet texture
GL.PushMatrix();
RenderTexture.active = _displaySheet;
GL.LoadPixelMatrix(0f, _displaySheet.width, _displaySheet.height, 0f);
Rect sourceRect = new Rect(0f, 0f, 1f, 1f);
float thumbSpace = 8f;
float thumbWidth = ((float)_displaySheet.width / (float)NumFrames) - thumbSpace;
float thumbHeight = thumbWidth / ((float)texture.width / (float)texture.height);
float thumbPos = ((thumbWidth + thumbSpace) * (float)_frameIndex);
Rect destRect = new Rect(thumbPos, (_displaySheet.height / 2f) - (thumbHeight / 2f), thumbWidth, thumbHeight);
Graphics.DrawTexture(destRect, texture, sourceRect, 0, 0, 0, 0);
RenderTexture.active = null;
GL.PopMatrix();
GL.InvalidateState();
}
private void ExtractNextFrame()
{
// Extract the frame to Texture2D
float timeSeconds = _frameIndex * _timeStepSeconds;
if (!_asyncExtract)
{
_texture = _mediaPlayer.ExtractFrame(_texture, timeSeconds, _accurateSeek, _timeoutMs);
ProcessExtractedFrame(_texture);
}
else
{
_mediaPlayer.ExtractFrameAsync(_texture, ProcessExtractedFrame, timeSeconds, _accurateSeek, _timeoutMs);
}
}
void OnGUI()
{
GUI.skin = _skin;
if (_displaySheet != null)
{
GUI.DrawTexture(new Rect(0f, 0f, Screen.width, Screen.height), _displaySheet, ScaleMode.ScaleToFit, false);
}
float debugGuiScale = 4f * (Screen.height / 1080f);
GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(debugGuiScale, debugGuiScale, 1.0f));
GUILayout.Space(16f);
GUILayout.BeginHorizontal(GUILayout.ExpandWidth(true), GUILayout.Width(Screen.width / debugGuiScale));
GUILayout.FlexibleSpace();
if (GUILayout.Button("Start Extracting Frames"))
{
_frameIndex = 0;
RenderTexture.active = _displaySheet;
GL.Clear(false, true, Color.black, 0f);
RenderTexture.active = null;
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
}
}