在线帮助中心对视频加载,过程优化,降低视频对服务端的负载

这篇具有很好参考价值的文章主要介绍了在线帮助中心对视频加载,过程优化,降低视频对服务端的负载。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 背景

大数据平台XSailboat 中包含 帮助中心 模块,提供在线的帮助文档和平台使用教程。

在帮助中心,不仅支持普通的文字,图片,还希望支持视频。
在线帮助中心对视频加载,过程优化,降低视频对服务端的负载,大数据平台开发技术,音视频,java,spring
前端网页显示出视频数据,在大数据平台的软件架构下,会经历这样的数据链路:
在线帮助中心对视频加载,过程优化,降低视频对服务端的负载,大数据平台开发技术,音视频,java,spring
在用户点击目录,打开文档时,其实他不一定会去看视频,为了提升效率,希望在用户点击观看视频的时候,才去加载视频。

在浏览器端,显示视频使用的是video字段。在默认情况下,当页面dom加载出来之后,会自动去加载视频数据。为了不让它自动加载,我们刚开始尝试了video的preload属性。它有auto、metadata、none三个属性可选。

  • auto,自动加载整个视频,
  • metadata,会加入头部一段视频之后刮起,等人去点击播放又重新打开一个流去读取
  • none,不加载视频,视频区域看起来一片黑

2. 实现方案

实现思路:

  1. 在视频类型的附件上传的时候,中台服务在往数据库里面写之前,从视频内容里面截取一帧图片。这样会有两个附件:一个视频附件,一个图片附件。从视频中提取出来的图片附件,它的id为“视频附件的id.poster”,类型为jpg。
  2. 前端显示的时候,设置video的poster属性,这个poster的链接地址就是步骤1提取到的附件地址。

3. 如何从视频中获得一帧poster(海报)

这里就需要使用java-cv库。这里的cv是 Computer Vision(计算机视觉)的缩写。

<dependency>
    <groupId>org.bytedeco</groupId>
    <artifactId>javacv-platform</artifactId>
    <version>1.5.9</version>
</dependency>

这个库依赖的东西是很多的,在导出的时候,可以只保留用到的那部分jar包。(后面给出最小jar包集合)

视频数据会以输入流(InputStream)的形式到达后台,在不用提取一帧图片的情况下,直接对接输入流和入库(Blob,这里后端数据库是PostgreSQL)的输出流即可。Spring JPA的代码如下:

// 省略...
@Column(name="file_data" )
@Comment("文件内容")
@Basic(fetch = FetchType.LAZY)
Blob fileData ;

public void setContent(InputStream aContent , long aLength)
{
	// fileData是附件类的一个属性,类型是java.sql.Blob
	fileData = BlobProxy.generateProxy(aContent, aLength) ; 
}
// 省略...

现在需要从流中提取出一帧图片,但对于Http连接的输入流,读了数据是无法回撤重读的。即大多数的流其实并不支持mark/reset特性。某个流是否支持mark/reset特性,调用InputStream的这个方法测试一下即可:

/**
* Tests if this input stream supports the <code>mark</code> and
* <code>reset</code> methods. Whether or not <code>mark</code> and
* <code>reset</code> are supported is an invariant property of a
* particular input stream instance. The <code>markSupported</code> method
* of <code>InputStream</code> returns <code>false</code>.
*
* @return  <code>true</code> if this stream instance supports the mark
*          and reset methods; <code>false</code> otherwise.
* @see     java.io.InputStream#mark(int)
* @see     java.io.InputStream#reset()
*/
public boolean markSupported() {
   // 省略...
}

如果一个流不支持mark/reset特性,可以通过BufferedInputStream包装一下,BufferedInputStream是支持mark/reset特性的,这样就能实现预览一部分数据,提取一帧图片,然后回到头上重新开始,将视频数据完整写入到数据库。
以下代码供参考:

public String createAttachment(String aDocId,
			InputStream aIns,
			long aOriginalFileSize,
			String aMediaType,
			String aOriginalFileName,
			String aUserId) throws IOException
{
	boolean isVideo = aMediaType.toLowerCase().startsWith("video/") ;
	byte[] pic =  null ;
	InputStream ins = aIns ;
	if(isVideo)
	{
		if(!ins.markSupported())
			ins = new BufferedInputStream(ins , 1024_000) ;
		ins.mark(1024_000) ;
		byte[] buf = new byte[1024_000] ;
		int len = 0 ;
		int readLen = 0 ;
		// 一次可能读不满buf的,得多次读取
		while(len < buf.length && (readLen = ins.read(buf , len , buf.length - len)) != -1)
		{
			len += readLen ;
		}
		ins.reset() ;
		
		ByteArrayInputStream bins = new ByteArrayInputStream(buf, 0, len) ;
		ByteArrayOutputStream bouts = new ByteArrayOutputStream(512_000);
//			FFmpegLogCallback.set() ;
		getVideoPic(bins, bouts) ;
		pic = bouts.toByteArray() ; 
	}
	
	Date now = new Date() ;
	
	DocAttachment athm = new DocAttachment();
	athm.setDocId(aDocId);
	athm.setContent(ins , aOriginalFileSize);
	athm.setFileName(aOriginalFileName);
	athm.setMediaType(aMediaType);
	athm.setLength(aOriginalFileSize);
	athm.setCreateUserId(aUserId);
	athm.setCreateTime(now) ;

	String id = mDocAthmRepo.save(athm).getId();
	if(isVideo)
	{
		String picId = id+".poster" ;
		
		athm = new DocAttachment();
		athm.setId(picId) ;
		athm.setDocId(aDocId);
		athm.setContent(new ByteArrayInputStream(pic) , pic.length);
		athm.setFileName(aOriginalFileName+".poster");
		athm.setMediaType(MediaType.IMAGE_JPEG_VALUE) ;
		athm.setLength(pic.length);
		athm.setCreateUserId(aUserId);
		athm.setCreateTime(now) ;
		
		mDocAthmRepo.save(athm) ;
	}
	return id ;
}

public static void getVideoPic(InputStream aIns, OutputStream aOuts) throws IOException
{
	try(FFmpegFrameGrabber ff = new FFmpegFrameGrabber(aIns)
			; Java2DFrameConverter converter = new Java2DFrameConverter())
	{
		ff.start();

		// 截取中间帧图片(具体依实际情况而定)
		int i = 0;
		int length = ff.getLengthInFrames();
		Assert.isTrue(length > 0, "%d 字节的视频数据,没有一帧完整图像!");
		Frame frame = null;
		while (i < length)
		{
			frame = ff.grabFrame();
			if (frame.image != null)
				break;
			i++;
		}

		// 截取的帧图片
		BufferedImage srcImage = converter.getBufferedImage(frame);
		ff.stop() ;
		int srcImageWidth = srcImage.getWidth();
		int srcImageHeight = srcImage.getHeight();

		// 对截图进行等比例缩放(缩略图)
		int width = 480;
		int height = (int) (((double) width / srcImageWidth) * srcImageHeight);
		BufferedImage thumbnailImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
		thumbnailImage	.getGraphics()
						.drawImage(srcImage.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0, 0, null);

		ImageIO.write(thumbnailImage, "jpg", aOuts);	
	}
}

4. java-cv最小jar包集合

完成提取一帧图像所需的最小jar包集合
在线帮助中心对视频加载,过程优化,降低视频对服务端的负载,大数据平台开发技术,音视频,java,spring文章来源地址https://www.toymoban.com/news/detail-823092.html

到了这里,关于在线帮助中心对视频加载,过程优化,降低视频对服务端的负载的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【CentOS】Linux 在线帮助文档命令:help、man 命令与文档汉化

    目录 1、Linux 的命令行模式 2、help 命令 3、man 命令 4、man 命令输出文档汉化         注:本文档使用 Linux 版本为 CentOS 7.9 1、Linux 的命令行模式         一般情况下,我们使用 Linux,都是通过特定的程序跟 Linux 系统进行沟通的,这个特定的程序就被称为壳程序(Shell),

    2024年01月24日
    浏览(46)
  • 有效和无效的帮助中心区别在哪?如何设计有效的帮助中心?

    帮助中心就是一个丰富的知识库,可以对企业的潜在客户进行引导。不仅能够提升用户的使用体验还能为企业塑造更加专业的品牌形象,在使用过程中为用户提供帮助。帮助中心的目的就是为了解决用户在使用过程中遇到的困难,同时为用户的使用提供引导。一些产品将帮助

    2024年02月05日
    浏览(41)
  • 这里有免费搭建高效帮助中心的方法!

    在现代的商业环境中,为客户提供高效的帮助中心是至关重要的。HelpLook是一个好用的知识库工具,可以帮助企业免费搭建高效的帮助中心。通过HelpLook,企业可以轻松创建和管理自己的知识库,提供详细的产品使用指南、常见问题解答等内容,以提升自助服务体验。 | 一、觉

    2024年02月06日
    浏览(39)
  • 帮助中心实践方式:及时提示反馈,引导自助解决

    为了及时高效的帮助用户解决当下实际问题,很多产品都会专门设置一个独立的产品帮助中心,满足客户需要获取解决方案的需要,减轻人工客服端压力。 常规的帮助中心文档和用户群,解决的是用户遇到问题或者疑问时,能寻找到文档、人来帮助自己解决问题或者疑惑,例

    2024年02月11日
    浏览(33)
  • 构建完善的帮助中心,降低企业客户服务成本

    随着信息技术的发展和应用的普及,越来越多的企业已开始意识到,通过构建完善的帮助中心,可以有效地降低企业客户服务成本,提高客户满意度。一个完善的帮助中心不仅仅是企业用于回答客户问题的工具,更是客户自主获取和消化信息的重要途径。 降低客户服务成本

    2024年02月06日
    浏览(47)
  • 通过wordpress能搭建有影响力的帮助中心

    wordpress建站服务是一种提供简单易用的工具和功能,帮助用户轻松创建和管理网站的服务。它适用于各类网站管理员、个人博主和小型企业主,无论是想要搭建个人博客、展示作品集还是开设在线商店,都可以通过wordpress建站服务来实现。 | 一、搭建帮助中心的重要性 在一个

    2024年02月06日
    浏览(65)
  • 帮助中心管理系统,人人都能用的知识管理平台

    帮助中心管理系统是一种知识管理平台,旨在帮助企业有效组织和管理知识资源,使其能够为客户和员工提供快速、准确的帮助和支持。 知识库管理: 帮助中心管理系统允许企业将知识组织和分类,建立一个完整的知识库。这包括常见问题解答(FAQs)、操作指南、故障排除

    2024年02月09日
    浏览(38)
  • 已解决chatgpt报错出了些问题。如果此问题仍然存在,请通过我们的帮助中心 help.openai.com 与我们联系。

    已解决chatgpt报错出了些问题。如果此问题仍然存在,请通过我们的帮助中心 help.openai.com 与我们联系。 粉丝群里面的一个小伙伴遇到问题跑来私信我,想用chatgpt,但是发生了报错(当时他心里瞬间凉了一大截,跑来找我求助,然后顺利帮助他解决了,顺便记录一下希望可以

    2023年04月14日
    浏览(54)
  • 音视频 FFmpeg如何查询命令帮助文档

    ffmpeg:超快音视频编码器 ffplay:简单媒体播放器 ffprobe:简单多媒体流分析器 基本信息:ffmpeg -h 高级信息:ffmpeg -h long 所有信息:ffmpeg -h full 所有信息:ffplay -h 所有信息:ffprobe -h ffmpeg/ffplay/ffprobe部分参数通用,部分参数不通用,在使用时需要注意 推荐一个零声学院项目课,个

    2024年02月12日
    浏览(60)
  • SpringBoot及Nacos配置中心加载顺序及覆盖生效关系

    目录 一、测试环境版本 二、测试结果 1、标准的SpringBoot应用 2、含有Nacos配置中心的SpringBoot应用 spring-boot-starter-parent  2.7.10 spring-cloud-starter-bootstrap  3.1.6 spring-cloud-starter-alibaba-nacos-config  2021.0.4.0 nacos-client 2.1.1 nacos服务端 2.2.1 1、标准的SpringBoot应用 在标准的SpringBoot应用中,

    2024年02月08日
    浏览(38)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包