当前位置: 首页 > news >正文

网站seo优化管理系统时尚手表网站

网站seo优化管理系统,时尚手表网站,凌河网站建设推广,3合一网站怎么做1、背景 最近在做视频转发的开发时#xff0c;遇到一个问题#xff0c;前端订阅播放h264视频流时#xff0c;有时会出现一段时间黑屏#xff0c;经过测试发现是没有收到关键帧#xff0c;只有第一帧是关键帧才能保证后续播放正常。所以后端需要实现一个功能#xff0c;就…1、背景 最近在做视频转发的开发时遇到一个问题前端订阅播放h264视频流时有时会出现一段时间黑屏经过测试发现是没有收到关键帧只有第一帧是关键帧才能保证后续播放正常。所以后端需要实现一个功能就是前端在进入播放页面时后端把最近的一个关键帧发过去。 2、思路环形缓存区 后端接收到的视频流是一个个的字节数组所以在接收时没法直接判断一帧的开始和结束需要将最近的一段视频流截取出来然后利用ffmpeg工具进行整体的解析和关键帧提取。 查看ffmpeg工具的代码可以发现ffmpeg工具入参是inputstream该工具会不断调用inputstream的read方法进行字节的读取。所以就想通过一个环形缓存区不断的记录最新的一段视频流数据。该环形缓存区再实现inputstream的接口重写read方法read读取的开始位置即是环形缓存区头到环形缓存区的尾时自动结束。 3、依赖包 !-- javacv -- dependencygroupIdorg.bytedeco/groupIdartifactIdjavacpp/artifactIdversion1.4.3/version /dependency dependencygroupIdorg.bytedeco/groupIdartifactIdjavacv/artifactIdversion1.4.3/version /dependency dependencygroupIdorg.bytedeco.javacpp-presets/groupIdartifactIdffmpeg-platform/artifactIdversion4.0.2-1.4.3/version /dependency 4、环形缓存区定义 public class CycleBufferInputStream extends InputStream {/************************************************ 环形缓冲区 ***********************************************/private ByteBuffer buffer null;private int readPos 0; //将要读取的位置private int writePos 0; //将要写入的位置private boolean isCycle false; //判断是否已经形成一个环public CycleBufferInputStream(int capacity) {this.buffer ByteBuffer.allocateDirect(capacity);}/*** 将字节数组以覆盖的方式放入环形缓冲区*/public void put(byte[] bytes) {int used buffer.capacity() - buffer.position();if (used bytes.length) {buffer.put(bytes, 0, used);buffer.clear();buffer.put(bytes, used, bytes.length - used);isCycle true;} else if (used bytes.length) {buffer.put(bytes, 0, used);buffer.clear();isCycle true;} else {buffer.put(bytes, 0, bytes.length);}writePos buffer.position();}/*** 定位读取的初始位置执行inputstream 读取前必须要先调用该方法*/public void readPrepare() {if (buffer.capacity() writePos || !isCycle) {readPos 0;} else {readPos buffer.position() 1;}}/*************************************************** 输入流传输 ***************************************************//*** Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255. If no byte is available because the end of the stream has been reached, the value -1 is returned. This method blocks until input data is available, the end of the stream is detected, or an exception is thrown.* A subclass must provide an implementation of this method.* Returns: the next byte of data, or -1 if the end of the stream is reached.* Throws: IOException – if an I/O error occurs.*/Overridepublic int read() throws IOException {if (readPos buffer.capacity()) readPos 0;if (readPos writePos) return -1;int value buffer.get(readPos);if (value 0) value value 256;return value;}} 5、从环形缓存区提取关键帧 /*** 从环形缓存环获取最近一帧关键帧字节数组* 这里返回的堆外内存所以注意要及时进行内存释放* param inputStream*/public static ByteBuffer dealVideo(InputStream inputStream) {try {int j 0;FFmpegFrameGrabber ff new FFmpegFrameGrabber(inputStream);ff.start();Frame frame null;Frame last null;while ((frame ff.grabKeyFrame()) ! null frame.image ! null) {last frame.clone();System.out.println(获取一帧 j);}ff.stop();if (last ! null) {System.out.println(获取最近的一个关键帧);ByteBuffer byteBuffer (ByteBuffer)last.image[0];return byteBuffer;}} catch (Exception e) {log.error(提取最近一个关键帧异常\n,e);}return null;} 6、使用 public static void main(String[] args) throws Exception {CycleBufferInputStream stream new CycleBufferInputStream(1024 * 1024 * 10);FileInputStream fis new FileInputStream(D:\\tmp-data\\1694511149969.h264);byte[] bytes new byte[fis.available()];fis.read(bytes);stream.put(bytes);stream.readPrepare();dealVideo(stream);} 7、扩展获取近期视频的截图 其实就是从近期的关键帧中提取出图片关键代码如下 public static void dealImage(InputStream inputStream) {try {Java2DFrameConverter converter new Java2DFrameConverter();FFmpegFrameGrabber ff new FFmpegFrameGrabber(inputStream);ff.start();int j 0;Frame frame null;Frame last null;while ((frame ff.grabImage()) ! null) {last frame.clone();System.out.println(获取一张图片 j);}ff.stop();if (last ! null last.image ! null) {System.out.println(存储最后一张图片 );BufferedImage fecthedImage converter.getBufferedImage(last);File screenshotFile new File(D:\\tmp-data\\, System.currentTimeMillis() .jpg);ImageIO.write(fecthedImage, jpg, screenshotFile);}} catch (Exception e) {log.error(提取最近一个图片异常\n,e);}} 8、整体代码 package com.qq.utils;import lombok.extern.slf4j.Slf4j; import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.Java2DFrameConverter;import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.*; import java.nio.ByteBuffer;Slf4j public class CycleBufferInputStream extends InputStream {/************************************************ 环形缓冲区 ***********************************************/private ByteBuffer buffer null;private int readPos 0; //将要读取的位置private int writePos 0; //将要写入的位置private boolean isCycle false; //判断是否已经形成一个环public CycleBufferInputStream(int capacity) {this.buffer ByteBuffer.allocateDirect(capacity);}/*** 将字节数组以覆盖的方式放入环形缓冲区*/public void put(byte[] bytes) {int used buffer.capacity() - buffer.position();if (used bytes.length) {buffer.put(bytes, 0, used);buffer.clear();buffer.put(bytes, used, bytes.length - used);isCycle true;} else if (used bytes.length) {buffer.put(bytes, 0, used);buffer.clear();isCycle true;} else {buffer.put(bytes, 0, bytes.length);}writePos buffer.position();}/*** 定位读取的初始位置执行inputstream方法前必须要先调用该方法*/public void readPrepare() {if (buffer.capacity() writePos || !isCycle) {readPos 0;} else {readPos buffer.position() 1;}}/*************************************************** 输入流传输 ***************************************************/Overridepublic int read() throws IOException {if (readPos buffer.capacity()) readPos 0;if (readPos writePos) return -1;int value buffer.get(readPos);if (value 0) value value 256;return value;}/*** 从环形缓存环获取最近一帧关键帧字节数组* 这里返回的堆外内存所以注意要及时进行内存释放* param inputStream*/public static ByteBuffer dealVideo(InputStream inputStream) {try {int j 0;FFmpegFrameGrabber ff new FFmpegFrameGrabber(inputStream);ff.start();Frame frame null;Frame last null;while ((frame ff.grabKeyFrame()) ! null frame.image ! null) {last frame.clone();System.out.println(获取一帧 j);}ff.stop();if (last ! null) {System.out.println(获取最近的一个关键帧);ByteBuffer byteBuffer (ByteBuffer)last.image[0];return byteBuffer;}} catch (Exception e) {log.error(提取最近一个关键帧异常\n,e);}return null;}public static void dealImage(InputStream inputStream) {try {Java2DFrameConverter converter new Java2DFrameConverter();FFmpegFrameGrabber ff new FFmpegFrameGrabber(inputStream);ff.start();int j 0;Frame frame null;Frame last null;while ((frame ff.grabImage()) ! null) {last frame.clone();System.out.println(获取一张图片 j);}ff.stop();if (last ! null last.image ! null) {System.out.println(存储最后一张图片 );BufferedImage fecthedImage converter.getBufferedImage(last);File screenshotFile new File(D:\\tmp-data\\, System.currentTimeMillis() .jpg);ImageIO.write(fecthedImage, jpg, screenshotFile);}} catch (Exception e) {log.error(提取最近一个图片异常\n,e);}}}
http://www.hkea.cn/news/14475644/

相关文章:

  • 杭州网站设计制作杭州市建设网
  • 淘宝优惠券网站怎么做 知乎wordpress文章关键字替换
  • 做室内意向图的网站wordpress伪静态化
  • 搜狗链接提交入口seo型网站
  • 网站建设企业 熊掌号一直免费的服务器万能视频播放器
  • 网站设计的主要风格2345纯净版推广包
  • 虹口区网站开发个人网站代做
  • seo搜索优化专员招聘郑州seo优化培训
  • pc网站建设怎么做怎么做可以看外国视频网站
  • 浙江建设集团网站网站建设扬州
  • 如何把网站建设成营销型网站如何自学建网站
  • 遵义做网站推广设计asp网站
  • 从化手机网站建设国庆网页制作素材
  • 湖州住房和城乡建设局网站公司行政负责做网站吗
  • 一加手机官网网站wordpress上传视频人50
  • 网站开发 语言 架构 数据库高新西区网站建设
  • 网站建设课程毕设千灯做网站
  • 个人网站建设分几个步走盘锦建设小学网站
  • WordPress分类获取子分类百度seo策略
  • 网站百度不到验证码怎么办手游推广平台
  • 怎么自己制作一个网站的书源20平办公室装修设计
  • 越秀网站建设策划vi手册免费模板
  • 郑州建设局官方网站wordpress拖拽式主题
  • 网站搭建报价表泰顺网站建设
  • 公司网站建设会计上怎么处理重庆前十装修公司排名
  • 推广网站链接怎么做中国服务外包网
  • 营销网站建设前期准备泰安营销型网站建设公司
  • 社交网站 模板logo设计
  • 网站扫二维码怎么做的有个人做网站的吗
  • 网站制作公司前十名云核wordpress