• JMF:Screen Grabber [DataSource]


    Screen Grabber [DataSource]
     

    To capture the contents of the screen and feed it to a JMF player or Processor for purposes such as saving screen shots to disk or transmitting live using RTP.
     

    Java 2 v.1.3 introduced a new class, Robot, that provides screen
    capture facilities. Since this is similar to capturing video from a VCR or
    camera, it is best encapsulated in a JMF DataSource object.
    This example  shows how to use Robot to create a screen capture DataSource.

    The DataSource is a PushDataSource that pushes captured screen shots at
    regular intervals to the connected Player or Processor.
    It creates a new  protocol "screen" with the following URL syntax:

                       screen://x,y,width,height/fps

    where x, y specify a screen location and width,height specify the size.
    fps specifies the number of frames to push per second. This can be any fraction
     greater than zero, although realistic values would be between 0.1 and 30.0.

    For example, to capture screen activity in the center of a 1024x768 screen, use
                        screen://352,264,320,240/5
     

    Compile the DataSource and LiveStream classes:
                  javac -d . DataSource.java LiveStream.java

    Run using JMStudio:
                  java JMStudio screen://0,0,160,120/10

    OR:
                 java    VideoTransmit   screen://0,0,160,120/10 224.122.122.122 2222
                 java    AVReceive2   224.122.122.122/2222

    Source Code:

                              DataSource.java
                              LiveStream.java
    /*
     * @(#)DataSource.java    1.2 01/03/02
     *
     * Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved.
     *
     * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
     * modify and redistribute this software in source and binary code form,
     * provided that i) this copyright notice and license appear on all copies of
     * the software; and ii) Licensee does not utilize the software in a manner
     * which is disparaging to Sun.
     *
     * This software is provided "AS IS," without a warranty of any kind. ALL
     * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
     * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
     * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
     * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
     * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
     * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
     * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
     * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
     * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGES.
     *
     * This software is not designed or intended for use in on-line control of
     * aircraft, air traffic, aircraft navigation or aircraft communications; or in
     * the design, construction, operation or maintenance of any nuclear
     * facility. Licensee represents and warrants that it will not use or
     * redistribute the Software for such purposes.
     
    */

    package com.sun.media.protocol.screen;

    import javax.media.Time;
    import javax.media.MediaLocator;
    import javax.media.protocol.*;
    import java.io.IOException;

    /**
     * This DataSource captures live frames from the screen.
     * You can specify the location, size and frame rate in the
     * URL string as follows:
     * screen://x,y,width,height/framespersecond
     * Eg:
     *    screen://20,40,160,120/12.5
     * Note:
     *    Requires JDK 1.3+ to compile and run
     
    */

    public class DataSource extends PushBufferDataSource {

        protected Object [] controls = new Object[0];
        protected boolean started = false;
        protected String contentType = "raw";
        protected boolean connected = false;
        protected Time duration = DURATION_UNBOUNDED;
        protected LiveStream [] streams = null;
        protected LiveStream stream = null;
        
        public DataSource() {
        }
        
        public String getContentType() {
        if (!connected){
                System.err.println("Error: DataSource not connected");
                return null;
            }
        return contentType;
        }

        public void connect() throws IOException {
         if (connected)
                return;
         connected = true;
        }

        public void disconnect() {
        try {
                if (started)
                    stop();
            } catch (IOException e) {}
        connected = false;
        }

        public void start() throws IOException {
        // we need to throw error if connect() has not been called
            if (!connected)
                throw new java.lang.Error("DataSource must be connected before it can be started");
            if (started)
                return;
        started = true;
        stream.start(true);
        }

        public void stop() throws IOException {
        if ((!connected) || (!started))
            return;
        started = false;
        stream.start(false);
        }

        public Object [] getControls() {
        return controls;
        }

        public Object getControl(String controlType) {
        return null;
        }

        public Time getDuration() {
        return duration;
        }

        public PushBufferStream [] getStreams() {
        if (streams == null) {
            streams = new LiveStream[1];
            stream = streams[0] = new LiveStream(getLocator());
        }
        return streams;
        }
    }
    /*
     * @(#)LiveStream.java    1.2 01/03/02
     *
     * Copyright (c) 1999-2001 Sun Microsystems, Inc. All Rights Reserved.
     *
     * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
     * modify and redistribute this software in source and binary code form,
     * provided that i) this copyright notice and license appear on all copies of
     * the software; and ii) Licensee does not utilize the software in a manner
     * which is disparaging to Sun.
     *
     * This software is provided "AS IS," without a warranty of any kind. ALL
     * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
     * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
     * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
     * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
     * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
     * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
     * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
     * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
     * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGES.
     *
     * This software is not designed or intended for use in on-line control of
     * aircraft, air traffic, aircraft navigation or aircraft communications; or in
     * the design, construction, operation or maintenance of any nuclear
     * facility. Licensee represents and warrants that it will not use or
     * redistribute the Software for such purposes.
     
    */


    package com.sun.media.protocol.screen;

    import java.awt.*;
    import java.awt.image.BufferedImage;
    import javax.media.*;
    import javax.media.format.*;
    import javax.media.protocol.*;
    import java.io.IOException;
    import java.util.StringTokenizer;

    public class LiveStream implements PushBufferStream, Runnable {

        protected ContentDescriptor cd = new ContentDescriptor(ContentDescriptor.RAW);
        protected int maxDataLength;
        protected int [] data;
        protected Dimension size;
        protected RGBFormat rgbFormat;
        protected boolean started;
        protected Thread thread;
        protected float frameRate = 1f;
        protected BufferTransferHandler transferHandler;
        protected Control [] controls = new Control[0];
        protected int x, y, width, height;

        protected Robot robot = null;

        public LiveStream(MediaLocator locator) {
        try {
            parseLocator(locator);
        } catch (Exception e) {
            System.err.println(e);
        }
        //size = Toolkit.getDefaultToolkit().getScreenSize();
        size = new Dimension(width, height);
        try {
            robot = new Robot();
        } catch (AWTException awe) {
            throw new RuntimeException("");
        }
        maxDataLength = size.width * size.height * 3;
        rgbFormat = new RGBFormat(size, maxDataLength,
                      Format.intArray,
                      frameRate,
                      32,
                      0xFF0000, 0xFF00, 0xFF,
                      1, size.width,
                      VideoFormat.FALSE,
                      Format.NOT_SPECIFIED);
        
        // generate the data
        data = new int[maxDataLength];
        thread = new Thread(this, "Screen Grabber");
        }

        protected void parseLocator(MediaLocator locator) {
        String rem = locator.getRemainder();
        // Strip off starting slashes
        while (rem.startsWith("/") && rem.length() > 1)
            rem = rem.substring(1);
        StringTokenizer st = new StringTokenizer(rem, "/");
        if (st.hasMoreTokens()) {
            // Parse the position
            String position = st.nextToken();
            StringTokenizer nums = new StringTokenizer(position, ",");
            String stX = nums.nextToken();
            String stY = nums.nextToken();
            String stW = nums.nextToken();
            String stH = nums.nextToken();
            x = Integer.parseInt(stX);
            y = Integer.parseInt(stY);
            width = Integer.parseInt(stW);
            height = Integer.parseInt(stH);
        }
        if (st.hasMoreTokens()) {
            // Parse the frame rate
            String stFPS = st.nextToken();
            frameRate = (Double.valueOf(stFPS)).floatValue();
        }
        }
        
        /***************************************************************************
         * SourceStream
         **************************************************************************
    */
        
        public ContentDescriptor getContentDescriptor() {
        return cd;
        }

        public long getContentLength() {
        return LENGTH_UNKNOWN;
        }

        public boolean endOfStream() {
        return false;
        }

        /***************************************************************************
         * PushBufferStream
         **************************************************************************
    */

        int seqNo = 0;
        
        public Format getFormat() {
        return rgbFormat;
        }

        public void read(Buffer buffer) throws IOException {
        synchronized (this) {
            Object outdata = buffer.getData();
            if (outdata == null || !(outdata.getClass() == Format.intArray) ||
            ((int[])outdata).length < maxDataLength) {
            outdata = new int[maxDataLength];
            buffer.setData(outdata);
            }
            buffer.setFormat( rgbFormat );
            buffer.setTimeStamp( (long) (seqNo * (1000 / frameRate) * 1000000) );
            BufferedImage bi = robot.createScreenCapture(
            new Rectangle(x, y, width, height));
            bi.getRGB(0, 0, width, height,
                  (int[])outdata, 0, width);
            buffer.setSequenceNumber( seqNo );
            buffer.setLength(maxDataLength);
            buffer.setFlags(Buffer.FLAG_KEY_FRAME);
            buffer.setHeader( null );
            seqNo++;
        }
        }

        public void setTransferHandler(BufferTransferHandler transferHandler) {
        synchronized (this) {
            this.transferHandler = transferHandler;
            notifyAll();
        }
        }

        void start(boolean started) {
        synchronized ( this ) {
            this.started = started;
            if (started && !thread.isAlive()) {
            thread = new Thread(this);
            thread.start();
            }
            notifyAll();
        }
        }

        /***************************************************************************
         * Runnable
         **************************************************************************
    */

        public void run() {
        while (started) {
            synchronized (this) {
            while (transferHandler == null && started) {
                try {
                wait(1000);
                } catch (InterruptedException ie) {
                }
            } // while
            }

            if (started && transferHandler != null) {
            transferHandler.transferData(this);
            try {
                Thread.currentThread().sleep( 10 );
            } catch (InterruptedException ise) {
            }
            }
        } // while (started)
        } // run

        
    // Controls
        
        public Object [] getControls() {
        return controls;
        }

        public Object getControl(String controlType) {
           try {
              Class  cls = Class.forName(controlType);
              Object cs[] = getControls();
              for (int i = 0; i < cs.length; i++) {
                 if (cls.isInstance(cs[i]))
                    return cs[i];
              }
              return null;

           } catch (Exception e) {   // no such controlType or such control
             return null;
           }
        }
    }
  • 相关阅读:
    《剑指offer》39题—数组中出现次数超过一半的数字
    常见排序算法实现
    剑指offer题目分类
    腾讯2019实习面试题
    Word2vec资料
    Hello World投票以太坊Dapp教程-Part1
    以太坊开发框架Truffle学习笔记
    linux查看端口进程占用情况
    重置fedora root密码
    docker挂载本地目录的方法总结
  • 原文地址:https://www.cnblogs.com/cuizhf/p/2219287.html
Copyright © 2020-2023  润新知