Xuggler被 弃用
,用谦卑视频代替。它已经带有一些演示项目,包括如何获取屏幕截图并将其转换为视频文件:RecordAndEnpreVideo.java
package io.humble.video.demos;import io.humble.video.*;import io.humble.video.awt.MediaPictureConverter;import io.humble.video.awt.MediaPictureConverterFactory;import org.apache.commons.cli.*;import java.awt.*;import java.awt.image.BufferedImage;import java.io.IOException;public class RecordAndEnpreVideo{ private static void recordScreen (String filename, String formatname, String precname, int duration, int snapsPerSecond) throws AWTException, InterruptedException, IOException { final Robot robot = new Robot(); final Toolkit toolkit = Toolkit.getDefaultToolkit(); final Rectangle screenbounds = new Rectangle(toolkit.getScreenSize()); final Rational framerate = Rational.make(1, snapsPerSecond); final Muxer muxer = Muxer.make(filename, null, formatname); final MuxerFormat format = muxer.getFormat(); final Codec prec; if (precname != null) { prec = Codec.findEncodingCodecByName(precname); } else { prec = Codec.findEncodingCodec(format.getDefaultVideoCodecId()); } Enprer enprer = Enprer.make(prec); enprer.setWidth(screenbounds.width); enprer.setHeight(screenbounds.height); // We are going to use 420P as the format because that's what most video formats these days use final PixelFormat.Type pixelformat = PixelFormat.Type.PIX_FMT_YUV420P; enprer.setPixelFormat(pixelformat); enprer.setTimebase(framerate); if (format.getFlag(MuxerFormat.Flag.GLOBAL_HEADER)) { enprer.setFlag(Enprer.Flag.FLAG_GLOBAL_HEADER, true); } enprer.open(null, null); muxer.addNewStream(enprer); muxer.open(null, null); MediaPictureConverter converter = null; final MediaPicture picture = MediaPicture.make(enprer.getWidth(), enprer.getHeight(), pixelformat); picture.setTimebase(framerate); final MediaPacket packet = MediaPacket.make(); for (int i = 0; i < duration / framerate.getDouble(); i++) { final BufferedImage screen = convertToType(robot.createScreenCapture(screenbounds), BufferedImage.TYPE_3BYTE_BGR); if (converter == null) { converter = MediaPictureConverterFactory.createConverter(screen, picture); } converter.toPicture(picture, screen, i); do { enprer.enpre(packet, picture); if (packet.isComplete()) { muxer.write(packet, false); } } while (packet.isComplete()); Thread.sleep((long) (1000 * framerate.getDouble())); } do { enprer.enpre(packet, null); if (packet.isComplete()) { muxer.write(packet, false); } } while (packet.isComplete()); muxer.close(); } @SuppressWarnings("static-access") public static void main (String[] args) throws InterruptedException, IOException, AWTException { final Options options = new Options(); options.addOption("h", "help", false, "displays help"); options.addOption("v", "version", false, "version of this library"); options.addOption(OptionBuilder.withArgName("format").withLongOpt("format").hasArg(). withDescription("muxer format to use. If unspecified, we will guess from filename").create("f")); options.addOption(OptionBuilder.withArgName("prec") .withLongOpt("prec") .hasArg() .withDescription("prec to use when encoding video; If unspecified, we will guess from format") .create("c")); options.addOption(OptionBuilder.withArgName("duration") .withLongOpt("duration") .hasArg() .withDescription("number of seconds of screenshot to record; defaults to 10.") .create("d")); options.addOption(OptionBuilder.withArgName("snaps per second") .withLongOpt("snaps") .hasArg() .withDescription("number of pictures to take per second (i.e. the frame rate); defaults to 5") .create("s")); final CommandLineParser parser = new org.apache.commons.cli.BasicParser(); try { final CommandLine cmd = parser.parse(options, args); final String[] parsedArgs = cmd.getArgs(); if (cmd.hasOption("version")) { // let's find what version of the library we're running final String version = io.humble.video_native.Version.getVersionInfo(); System.out.println("Humble Version: " + version); } else if (cmd.hasOption("help") || parsedArgs.length != 1) { final HelpFormatter formatter = new HelpFormatter(); formatter.printHelp(RecordAndEnpreVideo.class.getCanonicalName() + " <filename>", options); } else { final int duration = Integer.parseInt(cmd.getOptionValue("duration", "10")); if (duration <= 0) { throw new IllegalArgumentException("duration must be > 0"); } final int snaps = Integer.parseInt(cmd.getOptionValue("snaps", "5")); if (snaps <= 0) { throw new IllegalArgumentException("snaps must be > 0"); } final String precname = cmd.getOptionValue("prec"); final String formatname = cmd.getOptionValue("format"); final String filename = cmd.getArgs()[0]; recordScreen(filename, formatname, precname, duration, snaps); } } catch (ParseException e) { System.err.println("Exception parsing command line: " + e.getLocalizedMessage()); } } public static BufferedImage convertToType (BufferedImage sourceImage, int targetType) { BufferedImage image; // if the source image is already the target type, return the source image if (sourceImage.getType() == targetType) { image = sourceImage; } // otherwise create a new image of the target type and draw the new // image else { image = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), targetType); image.getGraphics().drawImage(sourceImage, 0, 0, null); } return image; }}也查看其他演示:humble-video-demos
我正在Webapp上实时使用它。
如果要实时流式传输,则需要RTSP服务器。您可以使用Red
5 Server,Wowza Streaming
Engine之类的大型框架,也可以使用Netty构建您自己的服务器,Netty自3.2版以来具有内置的RTSP编解码器。



