python捕获摄像头帧_Xuggler教程:帧捕获和视频创建

python捕获摄像头帧

注意:这是我们的“ Xuggler开发教程 ”系列的一部分。

到目前为止,在我们的Xuggler教程系列中,我们已经对视频处理的Xuggler进行了介绍,并讨论了转码和媒体修改 。 在本教程中,我们将看到如何解码视频和捕获帧,以及如何从头开始创建视频。

让我们开始解码视频流并以预定义的时间间隔捕获一些帧。 例如,可以使用它来制作媒体文件的缩略图 。 为此,我们将再次使用MediaTool API ,这是用于解码,编码和修改视频的高级API。

概念是打开媒体文件,循环播放特定的视频流,并以特定的间隔捕获相应的帧,将其转换为图像,然后将二进制内容转储到文件中。 这是所有这些代码的样子:

package com.javacodegeeks.xuggler;import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;import javax.imageio.ImageIO;import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.xuggler.Global;public class VideoThumbnailsExample {public static final double SECONDS_BETWEEN_FRAMES = 10;private static final String inputFilename = "c:/Java_is_Everywhere.mp4";private static final String outputFilePrefix = "c:/snapshots/mysnapshot";// The video stream index, used to ensure we display frames from one and// only one video stream from the media container.private static int mVideoStreamIndex = -1;// Time of last frame writeprivate static long mLastPtsWrite = Global.NO_PTS;public static final long MICRO_SECONDS_BETWEEN_FRAMES = (long)(Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES);public static void main(String[] args) {IMediaReader mediaReader = ToolFactory.makeReader(inputFilename);// stipulate that we want BufferedImages created in BGR 24bit color spacemediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);mediaReader.addListener(new ImageSnapListener());// read out the contents of the media file and// dispatch events to the attached listenerwhile (mediaReader.readPacket() == null) ;}private static class ImageSnapListener extends MediaListenerAdapter {public void onVideoPicture(IVideoPictureEvent event) {if (event.getStreamIndex() != mVideoStreamIndex) {// if the selected video stream id is not yet set, go ahead an// select this lucky video streamif (mVideoStreamIndex == -1)mVideoStreamIndex = event.getStreamIndex();// no need to show frames from this video streamelsereturn;}// if uninitialized, back date mLastPtsWrite to get the very first frameif (mLastPtsWrite == Global.NO_PTS)mLastPtsWrite = event.getTimeStamp() - MICRO_SECONDS_BETWEEN_FRAMES;// if it's time to write the next frameif (event.getTimeStamp() - mLastPtsWrite >= MICRO_SECONDS_BETWEEN_FRAMES) {String outputFilename = dumpImageToFile(event.getImage());// indicate file writtendouble seconds = ((double) event.getTimeStamp()) / Global.DEFAULT_PTS_PER_SECOND;System.out.printf("at elapsed time of %6.3f seconds wrote: %s\n",seconds, outputFilename);// update last write timemLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES;}}private String dumpImageToFile(BufferedImage image) {try {String outputFilename = outputFilePrefix + System.currentTimeMillis() + ".png";ImageIO.write(image, "png", new File(outputFilename));return outputFilename;} catch (IOException e) {e.printStackTrace();return null;}}}}

这看起来似乎有些不知所措,但确实非常简单。 让我为您提供一些详细信息。 我们首先从输入文件创建IMediaReader 。 媒体读取器用于读取和解码媒体。 由于我们希望将捕获的视频帧作为图像进行处理,因此我们使用setBufferedImageTypeToGenerate方法来表示这一点。 阅读器打开媒体容器,从中读取数据包,解码数据,然后将有关数据的信息分发到任何已注册的IMediaListener对象。 这是我们的自定义类ImageSnapListener起作用的地方。

我们的侦听器扩展了MediaListenerAdapter ,它是实现IMediaListener接口的适配器(提供空方法)。 通知实现此接口的对象有关视频处理期间生成的事件的信息。 我们只关心处理视频事件,因此我们仅实现IMediaListener.onVideoPicture方法。 在其中,我们使用提供的IVideoPictureEvent对象查找正在处理的流(仅视频)。

由于我们希望在特定时间捕获帧,因此我们不得不在时间戳上加点混乱。 首先,我们通过检查Global.NO_PTS常数的值来确保处理第一帧,该值意味着没有为给定对象设置时间戳。 然后,如果经过了最短的时间,我们通过调用IVideoPictureEvent.getImage方法来捕获帧,该方法返回基础BufferedImage 。 请注意,我们所说的是经过的视频时间,而不是“实时”。 然后,使用ImageIO.write实用程序方法将图像数据转储为PNG格式的文件。 最后,我们更新最后的写入时间。

让我们运行此应用程序以查看结果。 作为输入文件,我使用的是一个古老的Sun商业广告,它宣称“ Java无处不在 ”。 我已经在本地下载了提供的MP4版本。 输出控制台如下所示:

在经过0.000秒时写道:c:/snapshots/mysnapshot1298228503292.png
在10.010秒的经过时间写道:c:/snapshots/mysnapshot1298228504014.png
在20.020秒的经过时间写道:c:/snapshots/mysnapshot1298228504463.png

在经过时间130.063秒时写道:c:/snapshots/mysnapshot1298228509454.png
在经过140.007秒时写道:c:/snapshots/mysnapshot1298228509933.png
在经过150.017秒的时间时写道:c:/snapshots/mysnapshot1298228510379.png

视频总时间约为151秒,因此我们捕获了16帧。 这是我的文件夹中捕获的图像的样子:

好的,就是用来制作视频缩略图的。 现在让我们看看如何从头开始创建视频。 作为输入,我们将使用桌面上的顺序快照 。 这可以用于基本的屏幕记录应用程序。

为了创建视频,与到目前为止所见的MediaTool API相比,我们将不得不采取一些更底层的方法。 不过请不要担心,它不会很复杂。 主要思想是,我们创建一个媒体编写器,向其中添加一些流信息,对我们的媒体(屏幕截图图像)进行编码,然后关闭该编写器。 让我们看看用于实现此目的的代码:

package com.javacodegeeks.xuggler;import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.util.concurrent.TimeUnit;import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.ICodec;public class ScreenRecordingExample {private static final double FRAME_RATE = 50;private static final int SECONDS_TO_RUN_FOR = 20;private static final String outputFilename = "c:/mydesktop.mp4";private static Dimension screenBounds;public static void main(String[] args) {// let's make a IMediaWriter to write the file.final IMediaWriter writer = ToolFactory.makeWriter(outputFilename);screenBounds = Toolkit.getDefaultToolkit().getScreenSize();// We tell it we're going to add one video stream, with id 0,// at position 0, and that it will have a fixed frame rate of FRAME_RATE.writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_MPEG4, screenBounds.width/2, screenBounds.height/2);long startTime = System.nanoTime();for (int index = 0; index < SECONDS_TO_RUN_FOR * FRAME_RATE; index++) {// take the screen shotBufferedImage screen = getDesktopScreenshot();// convert to the right image typeBufferedImage bgrScreen = convertToType(screen, BufferedImage.TYPE_3BYTE_BGR);// encode the image to stream #0writer.encodeVideo(0, bgrScreen, System.nanoTime() - startTime, TimeUnit.NANOSECONDS);// sleep for frame rate millisecondstry {Thread.sleep((long) (1000 / FRAME_RATE));} catch (InterruptedException e) {// ignore}}// tell the writer to close and write the trailer if  neededwriter.close();}public static BufferedImage convertToType(BufferedImage sourceImage, int targetType) {BufferedImage image;// if the source image is already the target type, return the source imageif (sourceImage.getType() == targetType) {image = sourceImage;}// otherwise create a new image of the target type and draw the new imageelse {image = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), targetType);image.getGraphics().drawImage(sourceImage, 0, 0, null);}return image;}private static BufferedImage getDesktopScreenshot() {try {Robot robot = new Robot();Rectangle captureSize = new Rectangle(screenBounds);return robot.createScreenCapture(captureSize);} catch (AWTException e) {e.printStackTrace();return null;}}}

我们首先从给定的输出文件创建一个IMediaWriter 。 此类对媒体进行编码和解码,同时处理音频和视频流。 Xuggler猜测文件扩展名(在我们的情况下为MP4)的输出格式,并适当设置一些默认值。 然后,我们使用addVideoStream方法添加新的视频流,并提供其索引,使用的编解码器类型 (此处为MPEG-4 )和视频尺寸。 在此示例中,尺寸设置为等于屏幕尺寸的一半。

然后,我们执行一个循环,循环的次数等于所需的帧速率乘以所需的运行时间。 在循环内部,我们按照Java2D:带有Java屏幕快照的文章中的描述生成屏幕快照。 我们将屏幕快照作为BufferedImage检索,并将其转换为适当的类型( TYPE_3BYTE_BGR )(如果尚不存在)。

接下来,我们使用IMediaWriter.encodeVideo方法将图像编码为视频流。 我们提供流索引,图像,经过的视频时间和时间单位。 然后,我们根据所需的帧速率睡眠适当的时间。 循环结束后,根据视频格式,我们关闭编写器并编写预告片(这由Xuggler自动完成)。

如果我们执行该应用程序,则会创建一个视频,其中记录了您的桌面操作。 这是浏览JavaCodeGeeks网站时的静止图像:

伙计们,这是Xuggler的另一篇教程,描述了如何从输入文件中捕获视频帧以及如何使用桌面快照生成视频。 与往常一样,您可以下载为本教程创建的Eclipse项目 。 请继续关注JavaCodeGeeks上的更多Xuggler教程! 别忘了分享!

相关文章:

  • Xuggler视频处理简介
  • Xuggler教程:转码和媒体修改
  • 使用wowza和xuggler将RTMP转为RTSP

翻译自: https://www.javacodegeeks.com/2011/02/xuggler-tutorial-frames-capture-video.html

python捕获摄像头帧

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

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

相关文章

MyEclipse 编写 ExtJS 卡死问题解决方法

MyEclipse 8.6 在 jsp 中编写 ExtJS时&#xff0c;会出现卡死现象&#xff0c;让人甚是头疼。网上找了很多方法&#xff0c;折腾半天&#xff0c;还是不管用。 什么MyEclipse 优化&#xff0c;Validation 取消&#xff0c;MyEclipse 在 JSP 中打 "点" 时&#xff0…

java的aqs是什么,AQS在Java中的应用

上篇文章我们详细分析了AQS的底层实现原理,这节就来探索jdk中使用AQS实现的工具类ReentrantLock一, 是什么?怎么用?是什么?是一个独占锁,也就是在并发环境下同一时刻只能有一个线程获得资源,也是一个可重入锁.可重入锁: 一个线程已经获取到了该资源,下次再次获取资源时不会出…

php怎么把字符转成大写,php怎么把字符串转换为大写

php把字符串转换为大写的方法&#xff1a;可以利用内置函数strtoupper()来进行转换。strtoupper()函数可以把指定的字符串转换为大写&#xff0c;并返回被转换为大写的字符串。使用函数&#xff1a;(学习视频推荐&#xff1a;php视频教程)strtoupper() 函数把字符串转换为大写&…

oracle存储过程与函数的区别及作用,Oracle存储过程与存储函数-入门

文章思维导图一. 存储过程和存储函数的定义定义&#xff1a;存储在数据库中&#xff0c;供所有用户程序调用的子程序叫做存储过程/存储函数。复杂点的解释&#xff1a;存储过程(Stored Procedure)&#xff0c;就是一组用于完成特定数据库功能的SQL 语句集&#xff0c;该SQL语句…

CC++初学者编程教程(8) VS2013配置编程助手与QT

1. 2. 配置编程助手 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19&#xff0e; 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30&#xff0e; 31. 32&#xff0e; 33. 34. 35. 36. 37. 38. 39 40 41 42 43 这个时候我们就在VS2013里面集成了QT&#xff0c;编程助…

转子碰磨 matlab,航空科普:什么是航空发动机转子碰磨?

中国航空报讯&#xff1a;随着人们对航空发动机油耗、推重比等要求的逐步提高&#xff0c;提升航空发动机运行效率&#xff0c;尤其是提升民用航空发动机的经济性已经变得越来越重要。航空发动机的总体运行效率是气动效率、燃烧效率、冷却效率与机械效率等共同决定的。其中&…

Android 自定义 ListView 显示网络上 JSON 格式歌曲列表

本文内容 环境 项目结构 演示自定义 ListView 显示网络上 JSON 歌曲列表 参考资料 本文最开始看的是一个国人翻译的文章&#xff0c;没有源代码可下载&#xff0c;根据文中提供的代码片段&#xff0c;自己新建的项目&#xff08;比较可恶的是&#xff0c;没有图标图片资源&…

oracle 索引invisible,Oracle index unusable和invisible的区别

invisible index会被优化器所忽略&#xff0c;但是dml操作仍然会维护索引。在session或者system级别使用参数OPTIMIZER_USE_INVISIBLE_INDEX摘录自Oracle 11g的官方文档&#xff1a;UNUSABLE Specify UNUSABLE to mark the index or index partition(s) or index subpartition(…

php16进制密钥签名对接支付,简单理解rsa的加密和签名-PHP实现

我们先动手在linux上生成一下rsaPs&#xff1a;openssl是一堆加密算法和安全协议的开源集合,像RSA,DES,MD5,RC4等等,都能在openssl里面找到源代码.用openssl指定生成test.key文件&#xff0c;其中包含公钥私钥&#xff0c;1024为生成密钥长度tbtb:~/mimi$ openssl genrsa -out …

java中字符和字节的转换_Java最佳实践–字符到字节和字节到字符的转换

java中字符和字节的转换在使用Java编程语言时&#xff0c;我们将继续讨论与建议的实践有关的系列文章&#xff0c;我们将讨论String性能调优。 特别是&#xff0c;我们将着重于使用默认编码时如何有效地处理字符到字节和字节到字符的转换。 本文总结了两种建议的自定义方法与两…

Android实现简单短信发送器

布局&#xff1a; <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.android.com/tools"android:id"id/container"android:layout_width"match_parent"android:layout_heigh…

linux 查看文件哈希码,使用linux的sha1sum命令查看效验文件哈希值命令

服务器今天小编给大家分享的是使用linux的sha1sum命令查看效验文件哈希值命令&#xff0c;相信很多人都不太了解&#xff0c;为了让大家更加了解&#xff0c;所以给大家总结了以下内容&#xff0c;一起往下看吧。一定会有所收获的哦。sha1sum命令用于生成和校验文件的sha1值。它…

Java中的传值与传引用

曾经对java中传值还是传引用的问题十分困惑&#xff0c;而且也被问到过许多次&#xff0c;无论是面试&#xff0c;还是平时我们平时的讨论中。 在stackoverflow上面浏览时&#xff0c;无意中发现了跟这个问题有关的论题&#xff0c;于是深入地查看了&#xff0c;感觉获益匪浅&a…

java高性能序列化_Java最佳实践–高性能序列化

java高性能序列化在使用Java编程语言时&#xff0c;我们将继续讨论与建议的实践有关的系列文章&#xff0c;我们将讨论并演示如何将对象序列化用于高性能应用程序。 所有讨论的主题均基于用例&#xff0c;这些用例源于电信行业关键任务超高性能生产系统的开发。 在阅读本文的…

linux进程属主6,20150917 Linux进程查看与管理以及作业管理

第一、基础知识MBR引导--内核--内核程序--》协调其它程序一般内核运行在硬件之上&#xff0c;各应用也在硬件之前1)OS的基本功能&#xff1a;文件系统、网络功能、进程管理、内存管理、驱动程序、安全功能以上为通用目的设置的程序。&#xff0c;程序指令数据&#xff0c;程序运…

在javaweb中通过servlet类和普通类读取资源文件

javaweb有两种方式读取资源文件 在Servlet中读取&#xff0c;可以使用servletContext&#xff0c;servletContext可以拿到web所有的资源文件&#xff0c;然后随便读&#xff0c;但是这种方法不常用&#xff0c;尽量少在Servlet中读取资源文件 在普通Java类中&#xff08;DAO中&…

数学图形(1.43)贝壳形曲线与鱼形曲线

贝壳形曲线 #http://curvebank.calstatela.edu/naturalcurves/slide7.jpgvertices 12000t from 0 to (2*PI)r 10*(0.7 2.6*cos(t) 1.3*pow(sin(90*t), 3))x r*sin(t) y r*cos(t) 鱼形曲线 #http://www.2dcurves.com/quartic/quarticfi.html vertices 1000 t from 0 to…

linux下编译ios,为iOS安装OpenCV

一&#xff0c;要求CMake 2.8.8 或者更高Xcode 4.2 或者更新二&#xff0c;从Git库取得最新的 OpenCV使用 git 客户端从 http://github.com/itseez/opencv clone Open 库。在 max os x 下&#xff0c;可以通过以下命令行完成cd ~/git clone https://github.com/Itseez/opencv…

学习使用资源文件[11] - DLL 中的资源文件

本例将把一张 bmp 图片, 以资源文件的方式嵌入 dll, 然后再调用.第一步: 建一个 DLL 工程, 如图:然后保存, 我这里使用的名称都是默认的.第二步: 建一个资源原文件, 如图:编辑内容如下(路径中的文件一定要存在):img1 BITMAP "c:\temp\test.bmp"然后, 取个名(后缀须是…

linux 自动安装 yum,LINUX6安装YUM仓库和实现开机自动挂载

# LINUX6安装YUM仓库和实现开机自动挂载---------------------------------安装环境-------------------------------Redhat6镜像文件&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1DKH6adbrsipM-cTzH-wBgA 百度网盘 密码是hxcbVmware Workstation虚拟机工具&#x…