View difference between Paste ID: sJHwj0nW and
SHOW:
|
|
- or go back to the newest paste.
1 | - | |
1 | + | import com.xuggle.xuggler.Configuration; |
2 | import com.xuggle.xuggler.ICodec; | |
3 | import com.xuggle.xuggler.IContainer; | |
4 | import com.xuggle.xuggler.IContainerFormat; | |
5 | import com.xuggle.xuggler.IPacket; | |
6 | import com.xuggle.xuggler.IPixelFormat; | |
7 | import com.xuggle.xuggler.IRational; | |
8 | import com.xuggle.xuggler.IStream; | |
9 | import com.xuggle.xuggler.IStreamCoder; | |
10 | import com.xuggle.xuggler.IVideoPicture; | |
11 | import com.xuggle.xuggler.video.ConverterFactory; | |
12 | import com.xuggle.xuggler.video.IConverter; | |
13 | import java.awt.AWTException; | |
14 | import java.awt.Rectangle; | |
15 | import java.awt.Robot; | |
16 | import java.awt.image.BufferedImage; | |
17 | import java.io.IOException; | |
18 | import java.io.InputStream; | |
19 | import java.util.Properties; | |
20 | ||
21 | public class XugglerRtmpReferenceImpl { | |
22 | ||
23 | private static String url = "rtmp://your.test.server/screen/"; | |
24 | private static String fileName = "test/teststream"; | |
25 | private static int framesToEncode = 60; | |
26 | private static int x = 0; | |
27 | private static int y = 0; | |
28 | private static int height = 480; | |
29 | private static int width = 640; | |
30 | ||
31 | public static void main(String[] args) { | |
32 | IContainer container = IContainer.make(); | |
33 | IContainerFormat containerFormat_live = IContainerFormat.make(); | |
34 | containerFormat_live.setOutputFormat("flv", url + fileName, null); | |
35 | container.setInputBufferLength(0); | |
36 | int retVal = container.open(url + fileName, IContainer.Type.WRITE, containerFormat_live); | |
37 | if (retVal < 0) { | |
38 | System.err.println("Could not open output container for live stream"); | |
39 | System.exit(1); | |
40 | } | |
41 | IStream stream = container.addNewStream(0); | |
42 | IStreamCoder coder = stream.getStreamCoder(); | |
43 | ICodec codec = ICodec.findEncodingCodec(ICodec.ID.CODEC_ID_H264); | |
44 | coder.setNumPicturesInGroupOfPictures(5); | |
45 | coder.setCodec(codec); | |
46 | coder.setBitRate(200000); | |
47 | coder.setPixelType(IPixelFormat.Type.YUV420P); | |
48 | coder.setHeight(height); | |
49 | coder.setWidth(width); | |
50 | System.out.println("[ENCODER] video size is " + width + "x" + height); | |
51 | coder.setFlag(IStreamCoder.Flags.FLAG_QSCALE, true); | |
52 | coder.setGlobalQuality(0); | |
53 | IRational frameRate = IRational.make(5, 1); | |
54 | coder.setFrameRate(frameRate); | |
55 | coder.setTimeBase(IRational.make(frameRate.getDenominator(), frameRate.getNumerator())); | |
56 | Properties props = new Properties(); | |
57 | InputStream is = XugglerRtmpReferenceImpl.class.getResourceAsStream("/libx264-normal.ffpreset"); | |
58 | try { | |
59 | props.load(is); | |
60 | } catch (IOException e) { | |
61 | System.err.println("You need the libx264-normal.ffpreset file from the Xuggle distribution in your classpath."); | |
62 | System.exit(1); | |
63 | } | |
64 | Configuration.configure(props, coder); | |
65 | coder.open(); | |
66 | container.writeHeader(); | |
67 | long firstTimeStamp = System.currentTimeMillis(); | |
68 | long lastTimeStamp = -1; | |
69 | int i = 0; | |
70 | try { | |
71 | Robot robot = new Robot(); | |
72 | while (i < framesToEncode) { | |
73 | //long iterationStartTime = System.currentTimeMillis(); | |
74 | long now = System.currentTimeMillis(); | |
75 | //grab the screenshot | |
76 | BufferedImage image = robot.createScreenCapture(new Rectangle(x, y, width, height)); | |
77 | //convert it for Xuggler | |
78 | BufferedImage currentScreenshot = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); | |
79 | currentScreenshot.getGraphics().drawImage(image, 0, 0, null); | |
80 | //start the encoding process | |
81 | IPacket packet = IPacket.make(); | |
82 | IConverter converter = ConverterFactory.createConverter(currentScreenshot, IPixelFormat.Type.YUV420P); | |
83 | long timeStamp = (now - firstTimeStamp) * 1000; | |
84 | IVideoPicture outFrame = converter.toPicture(currentScreenshot, timeStamp); | |
85 | if (i == 0) { | |
86 | //make first frame keyframe | |
87 | outFrame.setKeyFrame(true); | |
88 | } | |
89 | outFrame.setQuality(0); | |
90 | coder.encodeVideo(packet, outFrame, 0); | |
91 | outFrame.delete(); | |
92 | if (packet.isComplete()) { | |
93 | container.writePacket(packet); | |
94 | System.out.println("[ENCODER] writing packet of size " + packet.getSize() + " for elapsed time " + ((timeStamp - lastTimeStamp) / 1000)); | |
95 | lastTimeStamp = timeStamp; | |
96 | } | |
97 | System.out.println("[ENCODER] encoded image " + i + " in " + (System.currentTimeMillis() - now)); | |
98 | i++; | |
99 | try { | |
100 | // sleep for framerate milliseconds | |
101 | Thread.sleep(Math.max((long) (1000 / frameRate.getDouble()) - (System.currentTimeMillis() - now), 0)); | |
102 | } catch (InterruptedException e) { | |
103 | e.printStackTrace(); | |
104 | } | |
105 | } | |
106 | } catch (AWTException e) { | |
107 | e.printStackTrace(); | |
108 | } | |
109 | container.writeTrailer(); | |
110 | } | |
111 | } |