Unity webgl 获取图片或视频数据

这一版有部分问题,使用最下面的…

WebFilePicker.jslib (放在Plugins目录)

var WebFilePickerLibrary = {
	/**
	 * 从浏览器中获取文件并发送给 Unity WebGL 应用程序。
	 * @param {number} objectNamePtr - Unity 对象名称的指针。
	 * @param {number} funcNamePtr - Unity 回调函数名称的指针。
	 * @param {number} fileTypePtr - 允许的文件类型字符串的指针。
	 * @param {number} allowMultiple - 是否允许多选(1 表示允许多选,0 表示单选)。
	 * @param {number} maxSizeMB - 文件大小限制(单位:MB)。如果 <=0,则无限制。
	 */
	getFileFromBrowser: function(objectNamePtr, funcNamePtr, fileTypePtr, allowMultiple, maxSizeMB) {
		var objectName = UTF8ToString(objectNamePtr);
		var funcName = UTF8ToString(funcNamePtr);
		var fileType = UTF8ToString(fileTypePtr);
		var maxSizeBytes = maxSizeMB > 0 ? maxSizeMB * 1048576 : 0;

		var input = document.createElement("input");
		input.type = "file";
		input.multiple = !!allowMultiple; // 转换为布尔值
		input.accept = fileType;
		input.style.display = "none";

		/**
		 * 处理通用文件
		 * @param {File[]} files - 用户选择的文件列表。
		 */
		var handleFiles = function(files) {
			var results = [];
			var filesProcessed = 0;

			for (let i = 0; i < files.length; i++) {
				const file = files[i];

				// 检查文件大小限制
				if (maxSizeBytes > 0 && file.size > maxSizeBytes) {
					SendMessage(objectName, funcName,
						`error:File '${file.name}' exceeds limit (${(file.size / 1048576).toFixed(1)}MB/${maxSizeMB}MB)`);
					return;
				}

				const reader = new FileReader();
				reader.onload = (e => {
					results.push({
						name: file.name,
						type: file.type,
						data: new Uint8Array(e.target.result)
					});

					filesProcessed++;

					// 所有文件处理完毕时发送结果
					if (filesProcessed === files.length) {
						var resultData = results.map(result => {
							return {
								name: result.name,
								type: result.type,
								data: Array.from(result.data)
							};
						});
						SendMessage(objectName, funcName, JSON.stringify(resultData));
					}
				});

				reader.readAsArrayBuffer(file);
			}
		};

		// 监听文件选择事件
		input.addEventListener('change', function(evt) {
			const files = evt.target.files;
			if (!files || files.length === 0) {
				SendMessage(objectName, funcName, "error:No file selected");
				return;
			}
			handleFiles(files);
		});

		// 触发文件选择对话框
		document.body.appendChild(input);
		input.click();
		document.body.removeChild(input);
	}
};

mergeInto(LibraryManager.library, WebFilePickerLibrary);

WebFilePicker.cs

using System;

namespace MYTOOL
{
    [Serializable]
    public class FileResult
    {
        public string name;     // 文件名称
        public string type;    // MIME 类型
        public byte[] data;    // 二进制数据
    }


    /// <summary>
    /// 提供与Unity WebGL平台交互的方法,用于从浏览器中获取文件(图片、视频或其他类型)
    /// </summary>
    public static class WebFilePicker
    {
        public const string IMAGE_FILE_TYPE = "image/*";
        public const string VIDEO_FILE_TYPE = "video/*";


#if UNITY_WEBGL
        [System.Runtime.InteropServices.DllImport("__Internal")]
        private static extern void getFileFromBrowser(string objName, string methodName, string fileType, bool allowMultiple, int maxSizeMB);
#endif


        /// <summary>
        /// 从浏览器中获取图片文件
        /// </summary>
        /// <param name="objName">Unity对象名称</param>
        /// <param name="methodName">Unity回调方法名称</param>
        /// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
        public static void GetImageFromBrowser(string objName, string methodName, int maxSizeMB = 0)
        {
            GetFileFromBrowser(objName, methodName, IMAGE_FILE_TYPE, maxSizeMB);
        }

        /// <summary>
        /// 从浏览器中获取多个图片文件
        /// </summary>
        /// <param name="objName">Unity对象名称</param>
        /// <param name="methodName">Unity回调方法名称</param>
        /// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
        public static void GetImagesFromBrowser(string objName, string methodName, int maxSizeMB = 0)
        {
            GetFilesFromBrowser(objName, methodName, IMAGE_FILE_TYPE, maxSizeMB);
        }

        /// <summary>
        /// 从浏览器中获取视频文件
        /// </summary>
        /// <param name="objName">Unity对象名称</param>
        /// <param name="methodName">Unity回调方法名称</param>
        /// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
        public static void GetVideoFromBrowser(string objName, string methodName, int maxSizeMB = 0)
        {
            GetFileFromBrowser(objName, methodName, VIDEO_FILE_TYPE, maxSizeMB);
        }

        /// <summary>
        /// 从浏览器中获取任意类型的文件
        /// </summary>
        /// <param name="objName">Unity对象名称</param>
        /// <param name="methodName">Unity回调方法名称</param>
        /// <param name="fileType">文件类型</param>
        /// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
        public static void GetFileFromBrowser(string objName, string methodName, string fileType, int maxSizeMB = 0)
        {
#if UNITY_WEBGL && !UNITY_EDITOR
            getFileFromBrowser(objName, methodName, fileType, false, maxSizeMB);
#else
            UnityEngine.Debug.LogError("only implemented for WebGL platform.");
#endif
        }

        /// <summary>
        /// 从浏览器中获取多个任意类型的文件
        /// </summary>
        /// <param name="objName">Unity对象名称</param>
        /// <param name="methodName">Unity回调方法名称</param>
        /// <param name="fileType">文件类型</param>
        /// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
        public static void GetFilesFromBrowser(string objName, string methodName, string fileType, int maxSizeMB = 0)
        {
#if UNITY_WEBGL && !UNITY_EDITOR
            getFileFromBrowser(objName, methodName, fileType, true, maxSizeMB);
#else
            UnityEngine.Debug.LogError("only implemented for WebGL platform.");
#endif
        }
    }
}

使用:调用WebFilePicker里提供的方法,回调时返回json字符串,反序列化为FileResult即可拿到原始数据。
注意:mime_type => type
在这里插入图片描述
效果:
在这里插入图片描述

统一格式返回(数组)
WebFilePicker.jslib (放在Plugins目录)

var WebFilePickerLibrary = {
    /**
     * 从浏览器中获取文件并发送给 Unity WebGL 应用程序。
     * @param {number} objectNamePtr - Unity 对象名称的指针。
     * @param {number} funcNamePtr - Unity 回调函数名称的指针。
     * @param {number} fileTypePtr - 允许的文件类型字符串的指针。
     * @param {number} allowMultiple - 是否允许多选(1 表示允许多选,0 表示单选)。
     * @param {number} maxSizeMB - 文件大小限制。如果<=0则无限制。
     */
    getFileFromBrowser: function (objectNamePtr, funcNamePtr, fileTypePtr, allowMultiple, maxSizeMB) {
        var objectName = UTF8ToString(objectNamePtr);
        var funcName = UTF8ToString(funcNamePtr);
        var fileType = UTF8ToString(fileTypePtr);
        var maxSizeBytes = maxSizeMB > 0 ? maxSizeMB * 1048576 : 0;

        var inputFile = document.createElement("input");
        inputFile.type = "file";
        inputFile.multiple = !!allowMultiple; // 转换为布尔值
        inputFile.accept = fileType;
        inputFile.style.display = "none";

        // 标记是否已完成操作
        let isHandled = false;

        /**
         * 处理通用文件
         * @param {File[]} files - 用户选择的文件列表。
         */
        var handleFiles = function (files) {
            var results = [];
            var filesProcessed = 0;

            for (let i = 0; i < files.length; i++) {
                const file = files[i];

                // 检查文件大小限制
                if (maxSizeBytes > 0 && file.size > maxSizeBytes) {
                    var errorResult = [{
                            result: -3,
                            name: file.name,
                            type: file.type,
                            data: []
                        }
                    ];
                    SendMessage(objectName, funcName, JSON.stringify(errorResult));
                    return;
                }

                const reader = new FileReader();
                reader.onload = (e => {
                    results.push({
                        result: 0,
                        name: file.name,
                        type: file.type,
                        data: Array.from(new Uint8Array(e.target.result))
                    });

                    filesProcessed++;

                    // 所有文件处理完毕时发送结果
                    if (filesProcessed === files.length) {
                        SendMessage(objectName, funcName, JSON.stringify(results));
                    }
                });

                reader.onerror = () => {
                    var errorResult = [{
                            result: -2,
                            name: file.name,
                            type: file.type,
                            data: []
                        }
                    ];
                    SendMessage(objectName, funcName, JSON.stringify(errorResult));
                };

                reader.readAsArrayBuffer(file);
            }
        };

        // 监听文件选择事件
        inputFile.addEventListener('change', function (evt) {
            isHandled = true;
            const files = evt.target.files;

            if (files.length > 0) {
                handleFiles(files);
            } else {
                var cancelResult = [{
                        result: -1,
                        name: "",
                        type: "",
                        data: []
                    }
                ];
                SendMessage(objectName, funcName, JSON.stringify(cancelResult));
            }

            // 清理 focus 监听器
            window.removeEventListener('focus', onFocus);
        });

        // 定义 focus 事件的回调函数
        var onFocus = () => {
            setTimeout(() => {
                if (!isHandled) {
                    var cancelResult = [{
                            result: -1,
                            name: "",
                            type: "",
                            data: []
                        }
                    ];
                    SendMessage(objectName, funcName, JSON.stringify(cancelResult));
                }
            }, 200);
        };

        // 监听窗口焦点事件(部分浏览器取消选择后会触发)
        window.addEventListener('focus', onFocus, {
            once: true
        });

        // 触发文件选择对话框
        document.body.appendChild(inputFile);
        inputFile.click();
        document.body.removeChild(inputFile);
    }
};

mergeInto(LibraryManager.library, WebFilePickerLibrary);

using System;

namespace MYTOOL
{
    [Serializable]
    public class FileSelectionResult
    {
        /// <summary>
        /// <para> 0 正常</para>
        /// <para>-1 取消</para>
        /// <para>-2 加载错误</para>
        /// <para>-3 文件大小超出限制</para>
        /// </summary>
        public int result;

        /// <summary>
        /// 文件名称
        /// </summary>
        public string name;

        /// <summary>
        /// MIME 类型
        /// </summary>
        public string type;

        /// <summary>
        /// 二进制数据
        /// </summary>
        public byte[] data;

        /// <summary>
        /// 是否操作成功
        /// </summary>
        public bool IsSuccess => result == 0;

        /// <summary>
        /// 用户是否取消了操作
        /// </summary>
        public bool IsCancelled => result == -1;

        /// <summary>
        /// 是否发生加载错误
        /// </summary>
        public bool IsLoadError => result == -2;

        /// <summary>
        /// 文件大小是否超出限制
        /// </summary>
        public bool IsSizeExceeded => result == -3;

        /// <summary>
        /// 获取状态描述信息
        /// </summary>
        public string StatusMessage =>
            result switch
            {
                0 => "操作成功",
                -1 => "用户取消",
                -2 => "加载错误",
                -3 => "文件大小超出限制",
                _ => "未知状态"
            };

        /// <summary>
        /// 判断是否有文件数据
        /// </summary>
        public bool HasFileData => data != null && data.Length > 0;

        /// <summary>
        /// 获取文件大小(以字节为单位),如果 data 为空则返回 0
        /// </summary>
        public long GetFileSize() => data?.Length ?? 0;
    }


    /// <summary>
    /// 提供与Unity WebGL平台交互的方法,用于从浏览器中获取文件(图片、视频或其他类型)
    /// </summary>
    public static class WebFilePicker
    {
        public const string IMAGE_FILE_TYPE = "image/*";
        public const string VIDEO_FILE_TYPE = "video/*";


#if UNITY_WEBGL
        [System.Runtime.InteropServices.DllImport("__Internal")]
        private static extern void getFileFromBrowser(string objName, string methodName, string fileType, bool allowMultiple, int maxSizeMB);
#endif


        /// <summary>
        /// 从浏览器中获取图片文件
        /// </summary>
        /// <param name="objName">Unity对象名称</param>
        /// <param name="methodName">Unity回调方法名称</param>
        /// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
        public static void GetImageFromBrowser(string objName, string methodName, int maxSizeMB = 0)
        {
            GetFileFromBrowser(objName, methodName, IMAGE_FILE_TYPE, maxSizeMB);
        }

        /// <summary>
        /// 从浏览器中获取多个图片文件
        /// </summary>
        /// <param name="objName">Unity对象名称</param>
        /// <param name="methodName">Unity回调方法名称</param>
        /// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
        public static void GetImagesFromBrowser(string objName, string methodName, int maxSizeMB = 0)
        {
            GetFilesFromBrowser(objName, methodName, IMAGE_FILE_TYPE, maxSizeMB);
        }

        /// <summary>
        /// 从浏览器中获取视频文件
        /// </summary>
        /// <param name="objName">Unity对象名称</param>
        /// <param name="methodName">Unity回调方法名称</param>
        /// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
        public static void GetVideoFromBrowser(string objName, string methodName, int maxSizeMB = 0)
        {
            GetFileFromBrowser(objName, methodName, VIDEO_FILE_TYPE, maxSizeMB);
        }

        /// <summary>
        /// 从浏览器中获取任意类型的文件
        /// </summary>
        /// <param name="objName">Unity对象名称</param>
        /// <param name="methodName">Unity回调方法名称</param>
        /// <param name="fileType">文件类型</param>
        /// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
        public static void GetFileFromBrowser(string objName, string methodName, string fileType, int maxSizeMB = 0)
        {
#if UNITY_WEBGL && !UNITY_EDITOR
            getFileFromBrowser(objName, methodName, fileType, false, maxSizeMB);
#else
            UnityEngine.Debug.LogError("only implemented for WebGL platform.");
#endif
        }

        /// <summary>
        /// 从浏览器中获取多个任意类型的文件
        /// </summary>
        /// <param name="objName">Unity对象名称</param>
        /// <param name="methodName">Unity回调方法名称</param>
        /// <param name="fileType">文件类型</param>
        /// <param name="maxSizeMB">文件大小限制。如果为0则无限制</param>
        public static void GetFilesFromBrowser(string objName, string methodName, string fileType, int maxSizeMB = 0)
        {
#if UNITY_WEBGL && !UNITY_EDITOR
            getFileFromBrowser(objName, methodName, fileType, true, maxSizeMB);
#else
            UnityEngine.Debug.LogError("only implemented for WebGL platform.");
#endif
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值