【小沐学Unity3d】Unity播放视频(VideoPlayer组件)

这篇具有很好参考价值的文章主要介绍了【小沐学Unity3d】Unity播放视频(VideoPlayer组件)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、简介

使用视频播放器组件可将视频文件附加到游戏对象,然后在运行时在游戏对象的纹理上播放。

  • 视频播放器 (Video Player) 组件:

unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

属性 功能
Source 选择视频源类型。Video Clip:将视频剪辑分配给视频编辑器。使用此字段来定义分配给视频播放器组件的视频剪辑。将视频文件拖放到此字段中,或单击该字段右侧的圆圈,然后从资源列表中选择文件(如果该文件位于 Project 文件夹中)。
Play On Awake 勾选 Play On Awake 复选框可在场景启动时播放视频。如果希望在运行时的另一个点触发视频播放,请取消勾选此复选框。此情况下可使用 Play() 命令通过脚本触发视频播放。
Render Mode 使用下拉选单来定义视频的渲染方式。Camera Far Plane:在摄像机的远平面上渲染视频。Camera Near Plane:在摄像机的近平面上渲染视频。Render Texture:将视频渲染到渲染纹理中。Material Override:通过游戏对象渲染器的材质将视频渲染到游戏对象的选定纹理属性中。API Only:将视频渲染到 VideoPlayer.texture 脚本 API 属性中。必须使用脚本将纹理分配给其预期目标。

2、脚本播放示例

以下脚本演示了 VideoPlayer 组件的一些功能。

  • (1)在层级树上新建一个空对象

unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

  • (2)在项目面板通过鼠标右键菜单,新建一个脚本对象,内容如下:
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#
// VideoPlayer 函数示例

using UnityEngine;

public class Example : MonoBehaviour
{
    void Start()
    {
        // 将一个 VideoPlayer 附加到主摄像机。
        GameObject camera = GameObject.Find("Main Camera");

        // 将 VideoPlayer 添加到摄像机对象时,
        // 它会自动瞄准摄像机背板,无需更改 videoPlayer.targetCamera。
        var videoPlayer = camera.AddComponent<UnityEngine.Video.VideoPlayer>();

        // Play on Awake 默认为 true。将它设置为 false 以避免下面设置的 URL
        // 自动开始播放,因为我们处于 Start() 状态。
        videoPlayer.playOnAwake = false;

        // 默认情况下,添加到摄像机的 VideoPlayer 将使用远平面。
        // 让我们改为瞄准近平面。
        videoPlayer.renderMode = UnityEngine.Video.VideoRenderMode.CameraNearPlane;

        // 这将使场景通过正在播放的视频可见。
        videoPlayer.targetCameraAlpha = 0.5F;

        // 设置要播放的视频。URL 支持本地绝对或相对路径。
        // 此处使用绝对路径。
        videoPlayer.url = "file:///D:/basketball.mp4";

        // 跳过前 100 帧。
        videoPlayer.frame = 100;

        // 完成后从头重新开始。
        videoPlayer.isLooping = true;

        // 每次到达结尾时,我们都会将播放速度减慢 10 倍。
        videoPlayer.loopPointReached += EndReached;

        // 开始播放。这意味着 VideoPlayer 可能需要做好准备工作(预留
        // 资源、预加载几帧等)。为了更好地控制此项准备工作
        // 带来的延迟,您可以使用 videoPlayer.Prepare() 及其
        // prepareCompleted 事件。
        videoPlayer.Play();
    }

    void EndReached(UnityEngine.Video.VideoPlayer vp)
    {
        vp.playbackSpeed = vp.playbackSpeed / 10.0F;
        Debug.Log("Video: End reached!");
    }
}
  • (3)将上面的脚本对象Example.script挂在上面新建的空对象上。
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#
  • (4)点击上面的播放按钮,
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#
  • (5)运行如下:
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

注意:URL 源选项会绕过资源管理,这意味着您必须手动确保 Unity 可以找到源视频。例如,一个 Web URL 需要由 Web 服务器托管源视频,而普通文件必须位于 Unity 可以找到该文件的位置(用脚本表示)。但是,如果内容不在 Unity 的直接控制之下,或者您希望避免在本地存储大型视频文件,则此功能非常有用。如果将视频播放器组件源设置为 URL,也可通过 http:// 和 https:// 从 Web 源读取视频。在这些情况下,Unity 会执行必要的预缓冲和错误管理。置于 Unity 的 StreamingAssets 文件夹中的文件可通过视频播放器组件的 URL 选项(见上文)进行使用,也可借助特定于平台的路径 (Application.streamingAssetsPath) 进行使用。

提示:Unity3d 拖拽脚本报错Can’t add the script component “” because the script class cannot be found
报错原因:文件名与文件内容中的类名不相符。c#文件创建以后再改名,会报错找不到对应类。类名和文件名要一致才行。(这个是Unity要求,c#本身不要求一致)

这里提供两段网上的示例脚本如下:

  • VideoScript1.cs:
using UnityEngine;
using UnityEngine.Video;
 
public class VideoScript1 : MonoBehaviour
{
    void Start () {
        var vPlayer = gameObject.AddComponent<VideoPlayer>();
        vPlayer.URL = "https://images.nvidia.cn/cn/youtube-replicates/p7RniXWvYhY.mp4";
        vPlayer.target = UnityEngine.Video.VideoTarget.CameraFrontPlane;
        vPlayer.alpha = 0.8f;
        vPlayer.prepareCompleted += Prepared;
        vPlayer.Prepare();
        Debug.Log("Video: Start!");
    }
 
    void Prepared(VideoPlayer vPlayer)
    {
        Debug.Log("Video: End reached!");
        vPlayer.Play();
    }
}
  • VideoScript2.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
using UnityEngine.UI;
using System;
 
public class VideoScript2: MonoBehaviour {
    //图像
    public RawImage image;
    //播放器
    public VideoPlayer vPlayer;
    public string urlNetWork = "http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4";//网络视频路径
    //播放
    public Button btn_Play;
    //暂停
    public Button btn_Pause;
    //前进
    public Button btn_Fornt;
    //后退
    public Button btn_Back;
    //下一个
    public Button btn_Next;
    //视频控制器
    public Slider sliderVideo;
    //音量控制器
    public Slider sliderSource;
    //音量大小
    public Text text;
    //当前视频时间
    public Text text_Time;
    //视频总时长
    public Text text_Count;
    //音频组件
    public AudioSource source;
    //需要添加播放器的物体
    public GameObject obj;
    //是否拿到视频总时长
    public bool isShow;
    //前进后退的大小
    public float numBer = 20f;
    //时 分的转换
    private int hour, mint;
    private float time;
    private float time_Count;
    private float time_Current;
    //视频是否播放完成
    private bool isVideo;
 
    // Use this for initialization
    void Start () {
        image = obj.GetComponent<RawImage>();
        //一定要动态添加这两个组件,要不然会没声音
        vPlayer = obj.AddComponent<VideoPlayer>();
        source = obj.AddComponent<AudioSource>();
 
        //这3个参数不设置也会没声音 唤醒时就播放关闭
        vPlayer.playOnAwake = false;
        source.playOnAwake = false;
        source.Pause();
 
        //初始化
        Init(urlNetWork);
 
        btn_Play.onClick.AddListener(delegate { OnClick(0); });
        btn_Pause.onClick.AddListener(delegate { OnClick(1); });
        btn_Fornt.onClick.AddListener(delegate { OnClick(2); });
        btn_Back.onClick.AddListener(delegate { OnClick(3); });
        btn_Next.onClick.AddListener(delegate { OnClick(4); });
 
        sliderSource.value = source.volume;
        text.text = string.Format("{0:0}%", source.volume * 100);
        sliderSource.onValueChanged.AddListener(delegate { ChangeSource(sliderSource.value); });
    }
 
    /// <summary>
    ///     初始化VideoPlayer
    /// </summary>
    /// <param name="url"></param>
    private void Init(string url) {
        isVideo = true;
        isShow = true;
        time_Count = 0;
        time_Current = 0;
        sliderVideo.value = 0;
        //设置为URL模式
        vPlayer.source = VideoSource.Url;
        //设置播放路径
        vPlayer.url = url;
        //在视频中嵌入的音频类型
        vPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource;
 
        //把声音组件赋值给VideoPlayer
        vPlayer.SetTargetAudioSource(0, source);
 
        //当VideoPlayer全部设置好的时候调用
        vPlayer.prepareCompleted += Prepared;
        //启动播放器
        vPlayer.Prepare();
    }
 
    /// <summary>
    ///     改变音量大小
    /// </summary>
    /// <param name="value"></param>
    public void ChangeSource(float value) {
        source.volume = value;
        text.text = string.Format("{0:0}%", value * 100);
    }
 
    /// <summary>
    ///     改变视频进度
    /// </summary>
    /// <param name="value"></param>
    public void ChangeVideo(float value) {
        if (vPlayer.isPrepared)
        {
            vPlayer.time = (long)value;
            Debug.Log("VideoPlayer Time:"+vPlayer.time);
            time = (float)vPlayer.time;
            hour = (int)time / 60;
            mint = (int)time % 60;
            text_Time.text = string.Format("{0:D2}:{1:D2}", hour.ToString(), mint.ToString());
        }
    }
 
    private void OnClick(int num) {
        switch (num)
        {
            case 0:
                vPlayer.Play();
                Time.timeScale = 1;
                break;
            case 1:
                vPlayer.Pause();
                Time.timeScale = 0;
                break;
            case 2:
                sliderVideo.value = sliderVideo.value + numBer;
                break;
            case 3:
                sliderVideo.value = sliderVideo.value - numBer;
                break;
            case 4:
                vPlayer.Stop();
                Init(Application.streamingAssetsPath + "/EasyMovieTexture.mp4");
                break;
            default:
                break;
        }
    }
     
    // Update is called once per frame
    void Update ()
    {
        if (vPlayer.isPlaying && isShow)
        {
            //把图像赋给RawImage
            image.texture = vPlayer.texture;
            //帧数/帧速率=总时长    如果是本地直接赋值的视频,我们可以通过VideoClip.length获取总时长
            sliderVideo.maxValue = vPlayer.frameCount/vPlayer.frameRate;
 
            time = sliderVideo.maxValue;
            hour = (int)time / 60;
            mint = (int)time % 60;
            text_Count.text = string.Format("/  {0:D2}:{1:D2}", hour.ToString(), mint.ToString());
 
            sliderVideo.onValueChanged.AddListener(delegate { ChangeVideo(sliderVideo.value); });
            isShow = !isShow;
        }
 
        if (Mathf.Abs((int)vPlayer.time - (int)sliderVideo.maxValue) == 0)
        {
            vPlayer.frame = (long)vPlayer.frameCount;
            vPlayer.Stop();
            Debug.Log("播放完成!");
            isVideo = false;
            return;
        }
        else if (isVideo && vPlayer.isPlaying)
        {
            time_Count += Time.deltaTime;
            if ((time_Count - time_Current) >= 1)
            {
                sliderVideo.value += 1;
                Debug.Log("value:" + sliderVideo.value);
                time_Current = time_Count;
            }
        }
    }
 
    private void FixedUpdate()
    {
 
    }
 
    void Prepared(VideoPlayer player) {
        player.Play();
    }
}

Unity5.6提供了多种生成Video Player控件的方式:

1、新建一个空白的Video Player:选择菜单栏的GameObject->Video->Video Player或者在Hierarchy面板上选择Create->Video->Video Player或者右击Hierarchy面板空白处选择Video->Video Player。
2、直接将导入的VideoClip拖入场景或者Hierarchy面板,生成的VideoPlayer控件的VideoClip将会自动被赋值,如果场景中存在MainCamera,Camera也会被自动赋值为MainCamera。
3、将导入的VideoClip拖动到场景中的Camera物体上,生成的VideoPlayer控件的VideoClip和MainCamera将会自动被赋值,模式默认选择Camera Far Plane。
4、将导入的VideoClip拖动到场景中的2D或者3D物体上,生成的VideoPlayer控件的VideoClip和Renderer将会自动被赋值,模式默认选择Material Override。
5、将导入的VideoClip拖动到场景中的UI物体上,生成的VideoPlayer控件的VideoClip将会自动被赋值,模式默认选择Render Texture。

VideoPlayer的脚本控制与AudioSource相似,有常规的Play,Pause,Stop方法,也有用于进度控制的time,isPlaying,isLooping,frame,frameCount等属性。
VideoPlayer可以使用一系列事件来监听播放的各个动作:

errorReceived: 错误监听到时被执行。
frameDropped :有丢帧发生时被执行。
frameReady :新的一帧准备好时被执行。
loopPointReached :播放结束或播放到循环的点时被执行。
prepareCompleted :视频准备完成时被执行。
seekCompleted :查询帧操作完成时被执行。
started:在Play方法调用之后立刻调用。

3、界面播放示例

3.1 2d界面全屏播放

  • (1)在层级树上鼠标右键新建一个视频播放对象如下:

unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

  • (2)设置视频对象的参数
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#
    Source:设置视频源,Video Clip或URL。这里使用Video Clip,它的视频资源在项目面板的Assets里面需要提前配置好相关视频资源。
    Render Mode:这里设置为在主相机上播放视频。

  • (3)新建一个脚本对象,绑定在视频播放对象上(当然也可以绑定在其他对象上),用来监控视频播放过程的事件。
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

Example2.cs:

using UnityEngine;
using UnityEngine.Video;

public class Example2 : MonoBehaviour
{
    public VideoPlayer vPlayer;

    void Awake()
    {
        vPlayer = GetComponent<VideoPlayer>();
        Debug.Log("Video: Awake";
    }

    void Start()
    {
        vPlayer.loopPointReached += VideoEnd;

        vPlayer.Play();//播放视频
        //vPlayer.Pause();//暂停视频
        //vPlayer.Stop();//停止视频
        //vPlayer.playbackSpeed = 1;//播放速度
        Debug.Log("Video: Start";
    }

    void Update()
    {
        Debug.Log("Video: Frame " + vPlayer.frame);
    }

    /// <summary>
    /// 监听视频是否播放结束,结束时调用
    /// </summary>
    /// <param name="vp"></param>
    void VideoEnd(VideoPlayer vp)
    {
        Debug.Log("爱看书的小沐:视频播放结束");
        Vp.Play();//重新播放视频
    }
}

点击系统的播放按钮运行如下:
unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

3.2 2d界面部分区域播放

在2D界面播放视频和在3D游戏体上播放,原理及代码是一样的,区别是要把Mesh组件换成RawImage,然后VideoPlayer的RenderMode选项选择RenderTexture或者其他选项。

这里需要把RenderMode 渲染模式改为 Rendertexture ,Canvas画布下创建 RawImage , 在Project 视图下创建 RenderTexture,将RenderTexture 拖入RawImage 的Texture中。

(1)新建一个视频播放对象,并改名为“小沐视频播放”。
unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

(2)在层级树上,新建一个raw image对象
unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#
新建之后在Canvas下面出现一个RawImage节点。
unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#
修改RawImage在屏幕上的位置;
unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

(3)Project 视图下创建 RenderTexture。它的属性可以保持默认,不修改。
unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#
(4)修改上面的RawImage对象的属性。将Texture属性关联上面新建的RenderTexture对象。
unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#
(4)修改上面的视频播放对象的属性。将Target Texture属性关联上面新建的RenderTexture对象。
unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#
(5)点击系统的播放按钮运行如下:
unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

3.3 3d模型表面播放

  • (1)新建一个视频播放对象,如上。

  • (2)新建一个立方体对象,如下
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

  • (3)修改视频对象的属性:
    设置视频源:Source
    设置渲染目标:Render Mode修改为Material Override,同时将Renderer修改为Cude(上面新建的立方体对象)。
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

  • (4)预览如下:
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#
    如果想在立方体的某一个面上播放的话,方法如下:

  • (5)在Cude对象下面新建一个网格对象Quad.
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

  • (6)并在三维空间中调整网格对象的位置,相对立方体。
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

  • (7)修改视频对象的属性:
    将Renderer的值修改为网格对象Quad.
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

  • (8)预览如下:
    unity videoplayer,Unity3d,C#.NET,unity,音视频,游戏引擎,unity3d,c#

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!文章来源地址https://www.toymoban.com/news/detail-622583.html

到了这里,关于【小沐学Unity3d】Unity播放视频(VideoPlayer组件)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【小沐学Unity3d】3ds Max 多维子材质编辑(Multi/Sub-object)

    多维子材质(Multi/Sub-object)是为一个模形(必须加载可编辑多边形或可编辑网格)的某部分指定一个才质ID,可以指定多个才质ID,然后给这个模形给才质时,每个ID的多维子才质对应一个同ID的模形部分。 (1) 多维子物体材质适用于对同一物体上适用2种或以上材质时适用。比

    2024年02月10日
    浏览(40)
  • 【小沐学Unity3d】3ds Max 骨骼动画制作(CAT、Character Studio、Biped、骨骼对象)

    官网地址: https://help.autodesk.com/view/3DSMAX/2018/CHS https://help.autodesk.com/view/3DSMAX/2019/CHS https://help.autodesk.com/view/3DSMAX/2020/CHS https://help.autodesk.com/view/3DSMAX/2021/CHS https://help.autodesk.com/view/3DSMAX/2022/CHS 3ds Max 包含两套完整的对各个角色设置动画的独立子系统(即 CAT 和 character studio),

    2024年02月08日
    浏览(41)
  • Unity3D教程:播放视频的两种方式

    Unity3D 中播放游戏视频的方式有两种,第一种是在游戏对象中播放,就好比在游戏世界中创建一个Plane面对象,摄像机直直的照射在这个面上。第二种是在GUI层面上播放视频。播放视频其实和贴图非常相像,因为播放视频用到的MovieTexture属于贴图Texture的子类,那么本章我们就

    2024年02月11日
    浏览(35)
  • Unity3DWEBGL播放本地视频用(VideoPlayer)

    大家好,本篇记录一下webgl播放视频,用的是videoPlayer组件, 不定时更新unity开发技巧,觉得有用记得一键三连哦。 接下来就一步步实现吧 unity播放本地视频 在Hierarchy面板右键创建VideoPlayer组件 到此UI就设置完成了 注意: 1.设置宽高,这个最好与视频的宽高匹配,或者同比例缩放

    2024年04月26日
    浏览(27)
  • Unity3d C#快速打开萤石云监控视频流(ezopen)支持WebGL平台,替代UMP播放视频流的方案(含源码)

    Universal Media Player算是视频流播放功能常用的插件了,用到现在已经不知道躺了多少坑了,这个插件虽然是白嫖的,不过被甲方和领导吐槽的就是播放视频流的速度特别慢,可能需要几十秒来打开监控画面,等待的时间较久。还有当输出WebGL的时候视频无法播放,这个问题也一

    2024年02月14日
    浏览(48)
  • 【Unity3D小技巧】Unity3D中Animation和Animator动画的播放、暂停、倒放控制

    推荐阅读 CSDN主页 GitHub开源地址 Unity3D插件分享 简书地址 我的个人博客 大家好,我是佛系工程师 ☆恬静的小魔龙☆ ,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 在日常开发中,常常会遇到要控制动画的播放、暂停和倒放的情况。 这篇文章就总结一下, Animation

    2024年02月02日
    浏览(88)
  • Unity3d C#利用本地网页快速打开萤石云监控视频流(ezopen)实现云台,声音等控制,支持WebGL平台,替代UMP播放(含源码)

    之前我介绍了替代Universal?Media?PlayerUMP播放石云监控视频流(ezopen)的功能,效果还是很明显的,笔者的测试是差不多3-5秒就能打开监控画面,不过稍微遗憾的是,之前的功能是iframe打开石云提供的播放网页的形式,功能基本只有画质切换,声音开关等;具体可以移步查看(https

    2024年02月13日
    浏览(43)
  • 【小沐学C++】C++ 实现视频文件播放(Windows Media Player、MFC、C#)

    无为也,则用天下而有余;有为也,则为天下用而不足。 https://docs.microsoft.com/en-us/windows/win32/wmp/about-the-windows-media-player-sdk Microsoft Windows Media Player 软件开发工具包 (SDK) 提供了用于自定义 Windows Media Player 和 Windows Media Player Mobile 以及使用 Windows Media Player ActiveX 控件和 Windo

    2024年02月06日
    浏览(40)
  • Unity3d 获取场景中摄像头视频流,实现直播效果(无需代码)

    下面是具体操作流程:   1. 搭建服务器,选用github 一个开源的 node.js服务器。 下载地址GitHub - iizukanao/node-rtsp-rtmp-server: RTSP/RTMP/HTTP hybrid server,点击克隆,选择ZIP下载。  2. 下载node.js( 官网链接 Node.js)   选择下载最新版本,并根据提示一步步安装即可。 3.搭建服务器。 找到

    2023年04月08日
    浏览(34)
  • Unity播放视频(一) VideoPlayer的使用

    1、在UI上添加脚本 添加UITexture脚本 用于显示视频 添加VideoPlayer 2、上代码

    2024年02月16日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包