Unity笔记之获取视频某一帧的图片
需求:获取到视频某一帧的图片(需要保存直接写file存下来即可)
原因:用户不可能上传视频的同时还会给你单独上传视频对应的一张图片,所以只能是我们自己从视频里面去随机抽取一张作为这个视频的缩略图来展示。
#region 获取视频某一帧图片
VideoPlayer video;
Texture2D videoTextrue;
RenderTexture renderTexture;
Sprite sprite;
void InitVideoToImage()//Start
{
videoTextrue = new Texture2D(2, 2);
video = GetComponent<VideoPlayer>();
video.url = path;
video.playOnAwake = false;
video.waitForFirstFrame = true;
video.sendFrameReadyEvents = true;
video.frameReady += GetNumTextrue;
video.Play();
}
int framesValue = 0;//获得视频第几帧的图片
/// <summary>
/// 获取到framesValue帧的Textrue
/// </summary>
void GetNumTextrue(VideoPlayer source, long frameIdx)
{
framesValue++;
if (framesValue == 1)
{
renderTexture = source.texture as RenderTexture;
if (videoTextrue.width != renderTexture.width || videoTextrue.height != renderTexture.height)
{
videoTextrue.Resize(renderTexture.width, renderTexture.height);
}
RenderTexture.active = renderTexture;
videoTextrue.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
videoTextrue.Apply();
RenderTexture.active = null;
video.frameReady -= GetNumTextrue;
video.sendFrameReadyEvents = false;
}
StartCoroutine(ScaleTexture(videoTextrue, 1920, 1080));
}
/// <summary>
/// 生成缩略图
/// </summary>
IEnumerator ScaleTexture(Texture2D source, int targetWidth, int targetHeight)
{
yield return new WaitForSeconds(2);
Texture2D result = new Texture2D(targetWidth, targetHeight, TextureFormat.ARGB32, false);
for (int i = 0; i < result.height; ++i)
{
for (int j = 0; j < result.width; ++j)
{
Color newColor = source.GetPixelBilinear((float)j / (float)result.width, (float)i / (float)result.height);
result.SetPixel(j, i, newColor);
}
}
result.Apply();
sprite = Sprite.Create(result, new Rect(0, 0, targetWidth, targetHeight), new Vector2(0.5f, 0.5f));
image.sprite = sprite;
}
#endregion
以上就是代码内容,弄进去直接用或者魔改
对了,这个有个缺点,就是视频必须播放着,不然没办法搞到。
(今天导出webgl测试了一下,发现问题很大,这个应该不支持webgl,webgl打开会获取不到视频的纹理)
如果只是播放mp4的话,绝大部分都是支持的,所以用自带的videoplayer就足够了,这样就没必要再去使用插件了。
下面是代码的内容:
using System.Collections;
using System.Collections.Generic;
using UMP;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;
public class NewBehaviourScript : MonoBehaviour
{
public Image image;
string path;
public VideoPlayer video;
// Start is called before the first frame update
void Start()
{
path = Application.streamingAssetsPath + "/中国机长.mp4";
video.url = path;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Q))
{
video.Play();
StartCoroutine(Video());
}
if (Input.GetKeyDown(KeyCode.W))
{
video.Pause();
}
if (Input.GetKeyDown(KeyCode.E))
{
video.Stop();
}
}
IEnumerator Video()
{
yield return new WaitForSeconds(1);
Texture2D t = TextureToTexture2D(video.GetComponent<RawImage>().texture);
image.sprite = GetSpriteByTexture(t);
}
/// <summary>
/// 运行模式下Texture转换成Texture2D
/// </summary>
/// <param name="texture"></param>
/// <returns></returns>
private Texture2D TextureToTexture2D(Texture texture)
{
Texture2D texture2D = new Texture2D(texture.width, texture.height, TextureFormat.RGBA32, false);
RenderTexture currentRT = RenderTexture.active;
RenderTexture renderTexture = RenderTexture.GetTemporary(texture.width, texture.height, 32);
Graphics.Blit(texture, renderTexture);
RenderTexture.active = renderTexture;
texture2D.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
texture2D.Apply();
RenderTexture.active = currentRT;
RenderTexture.ReleaseTemporary(renderTexture);
return texture2D;
}
/// <summary>
/// 把Texture2D转为Sprite
/// </summary>
/// <param name="tex"></param>
/// <returns></returns>
Sprite GetSpriteByTexture(Texture2D tex)
{
Sprite _sprite = Sprite.Create(tex, new Rect(0, 0, tex.width, tex.height), new Vector2(0.5f, 0.5f));
return _sprite;
}
}
有不对或者更好的方法欢迎指教!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!