Unity 获取视频缩略图

Posted DaLiangChen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity 获取视频缩略图相关的知识,希望对你有一定的参考价值。

一、简介

本章节将讲解使用Unity原生 VideoPlayer 组件,截取本地或网络视频帧,并生成缩略图。

二、案例实现

1.新建一个脚本并命名为 “VideoPreview.cs”。(代码如下)

using System.IO;
using UnityEngine;
using UnityEngine.Video;

/// <summary>获取视频预览</summary>
public class VideoPreview : MonoBehaviour

    /// <summary>获得视频第几帧的图片</summary>
    private int framesValue = 0;
    private VideoPlayer videoPlayer;
    private Texture2D videoFrameTexture;
    private RenderTexture renderTexture;
    /// <summary>视频保存路径</summary>
    private string videoUrl;
    /// <summary>视频预览图存放路径</summary>
    private string videoPreviewPath;

    public delegate void VideoThumbCompleteEvent(Texture2D texture);
    private VideoThumbCompleteEvent onCompleted;

    public static VideoPreview Create()
    
        GameObject go = new GameObject("VideoPreview");
        VideoPreview videoPreview = go.AddComponent<VideoPreview>();
        return videoPreview;
    

    private void OnDestroy()
    
        videoFrameTexture = null;
        renderTexture = null;
    

    /// <summary>
    /// 获取视频缩略图
    /// </summary>
    /// <param name="videoUrl">视频地址</param>
    /// <param name="completed">生成缩略图完成</param>
    public void VideoThumb(string videoUrl, VideoThumbCompleteEvent completed)
    
        this.onCompleted = completed;
        this.videoUrl = videoUrl;
        string[] nameArr = videoUrl.Split('/');
        string imageName = nameArr[nameArr.Length - 1];
        videoPreviewPath =  Application.persistentDataPath + "/" + imageName + ".png";

        videoFrameTexture = new Texture2D(2, 2);
        videoPlayer = gameObject.AddComponent<VideoPlayer>();
        videoPlayer.source = VideoSource.Url;
        videoPlayer.url = videoUrl;
        videoPlayer.playOnAwake = false;
        videoPlayer.waitForFirstFrame = true;

        videoPlayer.sendFrameReadyEvents = true;
        videoPlayer.frameReady += onFrameReady;
        videoPlayer.Play();
    

    private void onFrameReady(VideoPlayer source, long frameIdx)
    
        framesValue++;
        if (framesValue == 5)
        
            renderTexture = source.texture as RenderTexture;
            if (videoFrameTexture.width != renderTexture.width || videoFrameTexture.height != renderTexture.height)
            
                videoFrameTexture.Resize(renderTexture.width, renderTexture.height);
            
            RenderTexture.active = renderTexture;
            videoFrameTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
            videoFrameTexture.Apply();
            RenderTexture.active = null;
            videoPlayer.frameReady -= onFrameReady;
            videoPlayer.sendFrameReadyEvents = false;

            scaleTexture(videoFrameTexture, 600, 300, videoPreviewPath);
        
    

    //生成缩略图
    private void scaleTexture(Texture2D source, int targetWidth, int targetHeight, string savePath)
    
        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();
        File.WriteAllBytes(savePath, result.EncodeToJPG());
        if (onCompleted != null) onCompleted(result);
        Destroy(gameObject);
    


2.新建一个脚本,并命名为“Test.cs”,用来测试。(代码如下)

using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour

    /// <summary>用来显示视频1缩略图UI</summary>
    public RawImage rawImage01;
    /// <summary>用来显示视频2缩略图UI</summary>
    public RawImage rawImage02;
    /// <summary>用来显示视频3缩略图UI</summary>
    public RawImage rawImage03;

    /// <summary>视频路径1(可以本地或网络)</summary>
    private string videoUrl1 = "/Users/chenyongliang/Desktop/相册/1657100515231.mp4";
    /// <summary>视频路径2(可以本地或网络)</summary>
    private string videoUrl2 = "/Users/chenyongliang/Desktop/相册/1657100527594.mp4";
    /// <summary>视频路径3(可以本地或网络)</summary>
    private string videoUrl3 = "/Users/chenyongliang/Desktop/相册/1657100542642.mp4";

    private void Start()
    
        VideoPreview videoPreview1 = VideoPreview.Create();
        VideoPreview videoPreview2 = VideoPreview.Create();
        VideoPreview videoPreview3 = VideoPreview.Create();

        videoPreview1.VideoThumb(videoUrl1, (texture) =>
        
            rawImage01.texture = texture;
        );


        videoPreview2.VideoThumb(videoUrl2, (texture) =>
        
            rawImage02.texture = texture;
        );


        videoPreview3.VideoThumb(videoUrl3, (texture) =>
        
            rawImage03.texture = texture;
        );
    

3.新建3个 RawImage UI组件,用来显示视频缩略图。

以上是关于Unity 获取视频缩略图的主要内容,如果未能解决你的问题,请参考以下文章

Unity 获取视频缩略图

Unity 获得视频的某一帧,生成缩略图

Unity Prefab 缩略图全黑无法预览

C#获取本地视频的缩略图的方法都有哪些?

ios获取本地视频第一帧,缩略图

如何统一创建缩略图