vivo互联网视频播放体验优化的探索与实践

news2024/11/25 16:51:22

随着vivo互联网在视频业务领域的不断扩展,在多样化的业务场景下,如何提升每个用户的视频播放体验,保障最优的播放流畅度和清晰度,vivo互联网技术团队做了很多尝试与突破。LiveVideoStackCon 2022北京站邀请vivo互联网研发经理王道环,为我们介绍vivo互联网视频产品矩阵和技术架构,以及他们是如何打磨流畅度与内容感知编码并提升视频清晰度实际遇到的问题和解决方案。

文/王道环

编辑/LiveVideoStack

大家好,我是来自vivo互联网的王道环。我今天带来的分享是vivo互联网视频播放体验优化的探索与实践。

整个分享包括四个部分:

88c9e5c2179bcf25492b85d51e7d63d3.png

-01-

vivo视频业务介绍

68532f6e9285e2f26171b7acaf0e1009.png

首先给大家简单介绍下vivo视频业务。vivo互联网视频业务目前接入三大产品:

第一个是浏览器。浏览器是厂商自带工具属性,可以帮助用户搜索网页、提供图文信息流以及横版视频的服务。浏览器的日活目前接近1亿。

第二个产品是vivo短视频。它的内容调性主要以泛娱乐、泛生活为主,目前是我们着重发展的一个业务,后面我所讲到的案例也是以此业务来扩展。

第三个产品是i视频。i视频也比较成熟,目前日活接近2千万,主要提供横版的中长视频和影视内容。

170998ca10de49baf2e57d489a8aaf92.png

图为vivo视频处理技术中台架构。整个架构比较清晰、简单,包括整个视频的生命周期,从内容上传到视频处理,以及分发和播放。其中视频处理是最重要的核心模块。因为每天会面对用户UCG上传内容和MCN机构平台上传内容,这些内容质量参差不齐,码率和帧率都不一致。那么如何对这些视频进行转码和处理,以及画质增强,并呈现给用户,达到极致的体验,这是本模块最核心的使命。

视频分发是以CDN智能调度和质量检测为主。视频播放模块是以自研的播放器内核SDK为基础,包括自适应多码率和预加载策略等。QUIC主要是应对弱网场景,保证端侧播放流畅性。

底层基础服务部分,主要讲一下实验平台。因为做任何一轮技术优化,都要经过严格的用户分流,保证A/B实验均衡,同时也会做一些QoS和QoE的分析。对一些常规的技术优化,我们会分析QoS指标包括百秒卡顿时长、起播耗时、秒开率等。在QoE方面,主要包括用户平均播放时长、完播率等。对于一些更复杂的技术优化,我们还会做进一步的拆分,包括未播离开率、未播case的归因分析,以及整体网络请求链路的耗时等。

d1f092decb50a75a444110f4f8669296.png

在vivo短视频上线后,我们收到了大量站内外的用户负反馈,主要集中在画质不清晰、播放不流畅和卡顿等。 

c7e63fdf9beaf93fc4c311f74bacd0a1.png

那么怎样去衡量和优化这些体验?优化之后用户是否能真正满意而不是只停留在技术革新?对于视频业务来说,就是用简单、完美、优雅的方法来解决清晰度和流畅度问题。

-02-

打磨播放流畅度

接下来介绍一下我们是如何打磨播放流畅度的。

3c304ca30885f6627eecd1dd1571a51f.png

在vivo短视频上线之初,我们只是提供了单一分辨率的服务。这样就会导致两个问题,一是针对高端机型,如果被分发到低分辨率的如360p/480p的视频,清晰度相对较差,而这部分用户对画质要求很高,那么他们对产品就不会很满意。另外对于低端机型的用户,这部分手机的硬解性能较低,如果被分发到1080p以上的视频,那么就会造成播放卡顿。

为了快速解决这个问题,我们设置了多分辨率以及固定码率的阶梯转码策略。整体的实践方案是根据实际码率和分辨率的情况来分档转码策略。同时客户端也会根据用户的实时网速情况,进行档位切换。为了进一步提升转码效率,并节省成本,如右图所示,我们会根据播放量的情况进行转码。

ffd984798ea442b8e3938c20228a9786.png

图为MPEG4给到的分辨率和码率的建议设置图

如果我们只是按照这个标准去做,工作较为简单。但经过对线上数据分析发现,一些视频的播放场景是比较复杂的,切换比较多,这样可能会造成过度压缩的情况。另外一些视频的播放场景比较简单,如果按照此标准设置,就可能会造成带宽浪费,没有压缩到极致。

b449a459d3e130685334d8944e6290e5.png

我们目前面临的困难是:日增十万级内容,内容库有千万级内容,并且场景较为复杂,文件格式也比较混乱。所以我们的目标是:1、体验好。起播要快,画质要高。2、成本低。我们要选择最合适的压缩比例,让用户可以感受到最快的起播速度和最高的画质。

d3700748ea5c2ab4db1048b9d3b76dde.png

因此我们引入了自适应编码。自适应编码的目的是给不同复杂的视频挑选合适的编码方式,达到在相同画质的情况下,起到最低码率的效果。我们的自适应编码有三个特点:第一是基于Per-Segment思想,针对同一个视频划分不同场景,采用不同的编码策略;第二是我们会对原始视频进行一次基准转码,再结合一些特征,来预测“压缩比-质量分”曲线,从而成倍提升转码效率;第三是灵活参数决策,结合实际用户画像和业务特点,来选择合适的编码参数。

fb0e7a2ab4a0cac0fe19a9715285e444.png

自适应编码预测模型部分,重点分享下如何选取视频输入特征。分为四个部分:时空复杂度、码率、基准VMAF分和基准帧信息。时空复杂度代表了整个视频画面的复杂程度,一定程度上可以体现内容和场景的复杂程度;码率是影响视频质量的一个重要因素。码率越低,视频质量的分离程度越大;基准VMAF分帮助我们限定预测的曲线范围;基准帧信息辅助特征提取。

240f7e2387caac2f37de8995fdb2f562.png

接下来介绍如何解决单视频多场景问题。为了针对同一个视频去切分它的不同场景,首先会采用HSV像素变化阈值,进行场景分割。为了避免部分视频出现快速运动和光线变化带来的误差,我们会使用空间复杂度差值和I帧检测进行辅助。图中的案例即为实现场景分割的效果。

900b0ffe506dd6c6cf2eeb15a8051242.png

我们随机选取了一个线上视频。这个视频的特点是0-6s时画面相对简单,6-9是相对复杂。我们分别对其进行多场景分割以及常规压缩,可以看出,蓝色的多场景分割策略在0-6s时码率相对较低,在6-9s时相对较高。这也比较符合自适应编码的最初目标,即根据场景的复杂度、不同场景的复杂度情况来设定合理的码率。最终整体的视频码率也相对较低,而且VMAF分高于常规压缩策略,整体是符合预期的。

a5c7e9f7eb1077010d984ee65c7ddb93.png

我们来看下模型综合预测结果。图中有两条曲线,黄色的GT曲线和蓝色的预测曲线。右侧是loss图,可以看出随着迭代次数增加到万次后,loss值已经趋于0。我们可以根据基准转码的视频,把视频划为三档,分别为VMAF分差小于1、小于2、和小于3。这也是为了解决后面业务中遇到的问题。

4a82f26b5c31633c4a43993db4d78054.png

为了解决用户侧画质与流量的平衡问题,根据压缩比与VMAF分预测曲线及分档,我们自然就会联想到根据机型来制定不同的分发策略。对于高端机如XFold、XNote、X80Pro、iQOO9 Pro或新锐白领用户,他们对画质要求高且流量敏感度低,我们可以给其优先分发高档位视频,即VMAF与基准编码VMAF分差为1分,这些视频在用户侧播放表现更加流畅丝滑、观感也更好;对于中端机如S15、iQOO Neo等机型或一些小镇青年,这些用户群体对画质要求中等、流量敏感度一般,我们可以给其优先分发中档位视频;而对于千元机如Y系列机型,一般是下沉用户,比如资深蓝领或小镇中老年,这些用户往往会更在意流量使用,对画质要求不高,因此我们可以给其优先分发低档位视频。

6d9d7acdaa69badbe8d154e3c13cc4a2.png

接下来是业务场景的多样性分析。大家都知道,想要满足起播速度快、并发量高、画质也高这三个特点是非常有挑战的。

首先我们看热点推送场景,它的特点是新闻热点突发,瞬时千万级push,点击和并发量高。在没有预加载、客户端冷启动的情况下,对于起播速度要求也比较高。但这个场景下的码率是很低的,所以只对三特性中的两点有要求。

我们都知道,如果想保证起播速度快、能支持高并发量且画质最佳是一件非常难的事情,对技术难度和带宽成本来说要求都很高。

但是结合具体业务场景具体分析,似乎也没有一个场景很严苛地需要3个条件同时满足。拿热点推送场景来说,这类型的业务场景一般是大热点推送,往往是瞬时点击用户多,并发量高,客户端冷启动没有预加载的机会,因此对视频起播速度要求很高,画质方面,热点视频一般是新闻转发或编辑合成,此类视频画质要求并不高。

再者是外部引流场景,这类场景的特点是用户对视频感兴趣而被吸引到我们的app中,属于用户拉新,对于新用户来讲,画质高和起播快是必须同时具备的,对新用户的体验和留存也是最为关键的,但是拉新导流这种场景并发量不会太高。

最后是主推荐流场景,这也是我们最主要的场景,配合客户端灵活的预加载策略,我们只需要保证首条视频起播够快,剩下的视频由于已被提前加载,因此起播速度要求并不高,但是高画质和高并发是必须保证的。

a1e0c0cbbc4ac5b4883030b2c337a32a.png

对于vivo短视频3种典型的主流业务场景,我们采用不同的策略方案去处理。

从右图可以看出,码控策略会对视频的画质以及视频的码率波动产生较大的影响,对于点播VOD场景,业内常用的是CRF的码控模式,这种模式对视频的清晰度最为友好,但是通过线上实际的观察使用,我们发现,CRF倾向于在视频开头分配较大的码率,会对起播耗时产生负向的作用。在客户端冷启动无预加载起播时,这种负向效果会对业务产生较大影响。 

而热点推送场景要求起播快且瞬时并发量大,那么自适应决策优先分发低/中档视频,同时采用ABR的码控策略,以保证客户端冷启动能够秒播并节约带宽。外部引流场景要求起播快,那么我们采用ABR码控再优先分发中画质视频,保证导流的效率。最为重要的主推荐流场景,我们可以采用通用的CRF编码再优先分发高画质视频,保证用户的沉浸式浏览体验。

f434e1624b1c9db868507c3dd971c166.png

接下来看自适应编码的实验结果,通过播放vv加权,我们的视频整体平均码率与阶梯码率压缩方案相比,下降了10%,相应带来了卡顿的下降,但是VMAF分数得到了提升,这是符合预期的。因为自适应编码的目的就是在保证视频原有画质的基础上,让视频播放更流畅,带宽成本更低。

对于业务指标,短时间内是很难看到非常可观的收益,我们做实验的基本原则,就是如果业务指标没有显著负向,技术指标提升了,就可以持续扩大灰度量级。用户体验的提升是一个漫长的过程,我们的实验也持续了2个月之久,全量后,播放完成度、完播率、有效播放率也有一定的涨幅,符合预期。

-03-

提升视频清晰度

接下来我们看如何提升视频清晰度。

b227d1e47b8876cc60d3d531e878f446.png

我们对内容库里的视频做了盘点和分析,主要是低画质视频主要集中在噪声、伪影、模糊、分辨率低。

71b84e5e923fbb2fbd6e2c4012b4ba4b.png

要想做好画质增强,我们当前面临了一些挑战:

首先,相对于下采样方式已知的非盲设定,内容库里真是视频的退化是未知且多样化的,有些视频可能会叠加了多种不同程度的退化。对于这种情况,我们需深入分析视频的低质成因,设计合理的退化策略来辅助制定数据集,模拟真实的退化过程,这样训练集才更有针对性。

第二,就是细节合成和退化抑制之间难以权衡。展开来讲,一些超分算法经过长期传播能够聚合有用信息,生成更多细节输出。虽然长期传播会在视频轻度退化的情况下提高性能,合成更多细节,但严重的退化可能会通过传播被放大,从而损害输出视频的质量。因此为了平衡细节合成和退化抑制之间的权衡,我们引入了退化监督模块,在传播之前对一些较为严重的退化进行适当清理,以抑制退化被长期传播过度放大。

第三,是单一的训练模型难以覆盖多品类视频。之前有提到,我们内容库里视频品类繁多,因此有必要结合视频的场景和分类来定制化地合理设计相应的网络和损失函数,以满足不同分类视频的增强要求。

8b2f6acdc96be0e1d256998bfdc879cb.png

画质增强算法基于深度学习技术,分为四个模块:混合叠加退化、退化监督、双向空域特征传播和全局特征重建

混合叠加退化模块是针对原始视频叠加不同的退化,例如高斯噪声、泊松噪声、高斯模糊、视频压缩等,进一步模拟退化的复杂性和多样性。经过线上数据发现,不同场景的视频对于不同类型的退化敏感程度是不一样的,所以我们会辅以场景检测步骤,更真实模拟退化机制。

退化监督模块的目的是为了解决细节合成和退化抑制之间难以权衡的问题。

01b97ffd7770daa556fe6e970d9e307c.png

双向空域特征传播模块采用了前后向的双向传播,同时为了保证这些特征在时序上对齐,我们也采用了光流对齐的方案。同时对传播空域特征进行扭曲,以提升网络性能。

全局特征重建模块通过对传播特征进行卷积以及Pixel Shuffer上采样生成输出图像,以及通过对输入原始图像进行卷积和双线性插值上采样,与输出图像进行拼接,最终生成画质增强图像。

e83c5a83ea78471d6bedda02fc30b755.png

通过以上的画质增强算法,达到画质增强的效果。

30f2f10aae1aa31117774b023c246e9c.png

在上图的去模糊badcase中,我们进行添加不同模糊退化次数,以研究画质增强效果。模糊退化次数会分别添加0-3次,发现分数变高,但导致了字符形状的模糊,对整体视频呈现效果有较大影响。

8b02dae0b2648f99472a53cb92016726.png

根据上述的字幕badcase,我们使用以下的一些方式保护视频中的字幕,分为字幕保护训练和分类推理。

首先是损失函数调整。我们对存在字幕的视频,在训练的过程中加入了文本先验损失,测量的是从LR图像中提取的文本序列和从GT中提取的文本序列之间的L1范数和KL散度。

第二点是控制退化程度。对存在字幕的视频,减少模拟模糊退化的次数,以降低视频整体画质增强效果为代价,对视频的字幕进行保护。

第三点是数据集增强。我们对存在字幕的视频,在训练集中添加了大量来自不同自然场景的带有文本的视频,进行针对性的训练集加强是一种非常有效的方式。

第四点是视频字幕检测。通过字幕检测算法(预训练一个分类网络,判断视频中是否存在字幕)检测视频中是否存在字幕,再通过模型智能决策,对存在字幕的视频,选择经过上述三点针对性优化的模型进行画质增强。

b291dd0474e33f3366586489bc60b559.png

画质增强的线上实现会针对输入的低画质视频进行退化强度评测和视频场景分析,通过模型智能决策模块选择合适的增强模型和参数,再交由画质增强,以及加入画质评测步骤,最终实现线上画质增强。

cacda333a4ebc72aef714c5064a3bfe7.png

画质增强工程链路包括为前置分析、核心处理和后向分发。工程链路中主要是后向分发,前二者偏算法。最终增强处理后的视频是要面向用户的,所以视频码率、增强后的画质分是非常重要的指标。我们会结合业务特点和用户画像进行一轮自适应编码,把码率控制在合理范围内。然后是画质分析,包括系统和人工分析,最终分发给用户。

在线上有两个收集badcase的入口,一是人工评测和画质分析,二是线上提供的用户反馈入口,以不断补充训练集,迭代优化模型,使用户更满意。

856188bde99ce8137036dca1b480d73e.png

我们来看画质增强的实验收益。核心QoS指标有高清占比、平均画质分和卡顿率,均有较大幅度收益。核心QoE中的几个指标包括有效播放率、播放完成率和完播度也有一定增长。

-04-

总结与展望

接下来是总结与展望。

854b1bdc8bd8c921430d0a67f9a0cc62.png

总结一下,我们通过问题驱动、A/B实验和科学求证等手段进行优化方案制定以持续提升用户体验。

在打磨流畅度方面,我们围绕低成本和高体验,设计了场景自适应编码,目的是为了根据不同的场景分割,通过降低码率进一步优化成本,再结合实际业务特性和用户需求,做编码决策。

在提升清晰度方面,我们是通过退化监督、画质增强和画质评测来进行实现的。

f3b589d1842eff718f3e76a2ecc90149.png

关于未来的展望,我们希望探索在折叠屏的场景下播放体验升级,以及端云协同下的画质增强。

我的分享就到这里,谢谢大家。


d9476ad8f5bfe0a1ccd3d95815e1693a.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/596256.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSDN 富文本编辑器的优化建议(1)

CSDN 富文本编辑器的优化建议(1) 📚 写在前面:大家好~ 我是柠檬叶子C,今天是我在 C 站 1000 天创作纪念日!在这些日子里,我累计发布了 230 篇博客,这些博客无一例外都是用 C 站的 &q…

深眸科技创新视觉应用,AI+机器视觉为智能制造升级提供新视野

随着智能制造的进程不断加快,各大工业领域正在积极进行数字化转型,加速从制造到“智”造的转变。在全球制造业转型升级的浪潮下,从机器互联互通到人机协作再到无人工厂,机器视觉技术起到了重要作用。机器视觉用机器代替人眼&#…

easyui列表数据核对检查数据展示

1.easyui窗口内放置table列表 <div id"window_Id" class"easyui-window" title"异常参数列表展示" style"width:602px;height:493px;"data-options"closed:true,maximizable:false,resizable:true,minimizable:false,shadow:…

031:Mapbox GL实现地图导航功能,可选择起始点、路线、通行方式

第031个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中实现地图导航功能,可选择起始点、路线、通行方式。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共71行)安装插件相关API参考:专栏目标示例效果…

《Java并发编程实战》课程笔记(七)

Java 线程 Java 线程的生命周期 通用的线程生命周期 通用的线程生命周期基本上可以用下图这个“五态模型”来描述。这五态分别是&#xff1a;初始状态、可运行状态、运行状态、休眠状态和终止状态。 Java 中线程的生命周期 Java 语言中线程共有六种状态&#xff0c;分别是…

Pytorch入门(三)深度学习模型的训练的基本步骤

文章目录 一、修改现有的网络模型二、模型的保存三、模型的加载四、模型的评估五、训练模型的完整套路六、使用GPU加速模型的训练七、模型训练完整的验证套路 一、修改现有的网络模型 import torchvision from torch import nn # pretrained 为True时会自动下载模型所对应的权…

ES6-ES13学习笔记(4.0)

includes函数 判断字符串是否存在指定字符 <!--* Author: RealRoad1083425287qq.com* Date: 2023-06-01 08:40:33* LastEditors: Mei* LastEditTime: 2023-06-01 08:58:54* FilePath: \vscode\ECMA\05\01.html* Description: * * Copyright (c) 2023 by ${git_name_ema…

Docker+Jenkins+Gitee自动化部署maven项目

1.简介 各位看官老爷&#xff0c;本文为Jenkins实战&#xff0c;注重实际过程&#xff0c;阅读完会有以下收获&#xff1a; 了解如何使用Docker安装Jenkins了解如何使用Jenkins部署maven项目了解如何使用JenkinsGitee实现自动化部署 2.Jenkins介绍 相信&#xff0c;正在读这…

美国频频对中国芯片出手,却没想到最先倒下的是美芯巨头

据报道指出全球知名的硬盘厂商西部数据已基本敲定与日本存储芯片巨头铠侠的合并计划&#xff0c;不过让人意外的是最终主导者将是铠侠而不是西部数据&#xff0c;这意味着西部数据将从此消失于历史之中。 西部数据是全球最大的硬盘厂商&#xff0c;它先后收购了知名硬盘厂商希捷…

【实用篇】Docker

文章目录 Docker实用篇1.初识Docker1.1.什么是Docker1.1.1.应用部署的环境问题1.1.2.Docker解决依赖兼容问题1.1.3.Docker解决操作系统环境差异1.1.4.小结 1.2.Docker和虚拟机的区别1.3.Docker架构1.3.1.镜像和容器1.3.2.DockerHub1.3.3.Docker架构1.3.4.小结 1.4.安装Docker1.…

springboot+vue高校班级管理系统 java 同学录校友录网站

本海滨学院班级回忆录管理员功能有个人中心&#xff0c;用户信息管理&#xff0c;班委信息管理&#xff0c;班级信息管理&#xff0c;加入班级管理&#xff0c;新闻信息管理&#xff0c;班级相册管理&#xff0c;活动信息管理&#xff0c;捐赠信息管理&#xff0c;论坛信息管理…

界面控件DevExpress ASP.NET新主题——Office 365暗黑主题的应用

DevExpress ASP.NET Web Forms Controls拥有针对Web表单&#xff08;包括报表&#xff09;的110种UI控件&#xff0c;DevExpress ASP.NET MVC Extensions是服务器端MVC扩展或客户端控件&#xff0c;由轻量级JavaScript小部件提供支持的70个高性能DevExpress ASP.NET Core Contr…

2023年6月跟教授学DAMA-CDGA/CDGP数据治理认证到这里

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

什么?要求设计一个循环队列?

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;推荐专栏: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f354;&#x1f35f;&#x1f32f;C语言进阶 &#x1f511;个人信条: &#x1f335;知行合一 &#x1f349;本篇简介:>:讲解用c…

PortSwigger 基于不安全的反序列化漏洞

一、反序列化漏洞简单介绍 反序列化漏洞是指攻击者通过在应用程序中注入恶意的序列化对象来利用应用程序的反序列化功能&#xff0c;从而导致应用程序受到攻击的漏洞。 在一些编程语言和应用程序中&#xff0c;对象可以被序列化为一些字节流或字符串&#xff0c;然后在不同的应…

基于Java+SpringBoot+Vue前后端分离网课在线学习观看系统

博主介绍&#xff1a;✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

C#正则表达式的使用

C#正则表达式 System.Text.RegularExpressions.Regex 使用时需要引入命名空间 using System.Text.RegularExpressions; 如果不引用则写成 System.Text.RegularExpressions.Regex 使用方法如下&#xff1a; string str"测试123456"; string result""; re…

chatgpt赋能python:Python代码中的符号

Python代码中的符号 Python是一种简单易学的编程语言&#xff0c;拥有着广泛的应用领域&#xff0c;比如数据分析、人工智能、Web开发等等。在Python的编程过程中&#xff0c;符号是我们必须要熟悉的一部分。在本文中&#xff0c;我们将介绍Python代码中常见的符号&#xff0c…

华为OD机试真题B卷 Java 实现【人民币转换】,附详细解题思路

一、题目描述 考试题目和要点&#xff1a; 中文大写金额数字前应标明“人民币”字样。中文大写金额数字应用壹、贰、叁、肆、伍、陆、柒、捌、玖、拾、佰、仟、万、亿、元、角、分、零、整等字样填写。中文大写金额数字到“元”为止的&#xff0c;在“元”之后&#xff0c;应…

【Python PyInstaller】零基础也能轻松掌握的学习路线与参考资料

一、Python PyInstaller介绍 Python PyInstaller是一个用于将Python应用程序打包成可执行文件的工具&#xff0c;支持Windows、Mac OS X和Linux平台。使用PyInstaller可以方便地将Python应用程序和所需的依赖项&#xff08;包括Python解释器本身&#xff09;打包成一个独立的可…