在Java中的套接字上循环传输时,我只得到一张图像 [英] I get only one image while transferring in a loop over a socket in java

查看:92
本文介绍了在Java中的套接字上循环传输时,我只得到一张图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上我想做的是用Java实现实时视频流.即抓取一台计算机的网络摄像头的视频,并将该视频实时发送到另一台计算机

What basically i want to do is implement live video streaming in java. i.e grab video infront of webcam of one computer and send that video to other computer in real time

这是我的服务器端代码,我在其中使用opencv库循环捕获图像,然后将其保存到文件中. 然后,我使用Filestream打开它,并将其发送到其他网络,下面是我的客户端代码

This is my server side code where i grab images in a loop using opencv libraries and and then save it to a file. I then open it using a Filestream and send it to other network and below is my client side code

错误: 我在客户端仅获得一张图像,即从网络摄像头捕获的第一张图像

Error: I get only one image on client side i.e the first captured image from webcam

获取所有图像(即在客户端上作为视频)的解决方法是什么

What is the workaround to get all images i.e as a video on client side

我已经导入了所有必需的程序包

I have imported all the necessary packages

     public class filesen{
       static IplImage bimg;
       public static void main(String ar[])throws Exception{
           Socket clientSocket=new Socket("localhost",1234);
           CanvasFrame canvas = new CanvasFrame("sending");
           //int i=1;
           FrameGrabber grabber = new OpenCVFrameGrabber("");
           try {
                grabber.start();
                IplImage img;
                while (true) {
                OutputStream out=clientSocket.getOutputStream();
                img = grabber.grab();
                if (img != null) {

                        opencv_highgui.cvSaveImage("a.jpg", img); 

                        FileInputStream fis=new FileInputStream("a.jpg");
                        System.out.println(fis);
                        int x=0;
                        while(true){
                                x=fis.read();
                                if(x==-1)break;
                                out.write(x);
                            }
                        bimg = opencv_highgui.cvLoadImage("a.jpg");
                        canvas.showImage(bimg);
                    //    out.close();
                        //canvas.showImage(img);
                    i++;
                    System.out.println(i);
                    }

                }

        }
        catch (Exception e) {
        }
    }
}

这是我的客户端代码

public class filere extends Applet {
  //static IplImage bimg;
  public static void main(String ar[]) throws Exception{
    CanvasFrame canvas = new CanvasFrame("Webcam");
    ServerSocket ss=new ServerSocket(1234);
   while(true){
    Socket clientSocket=ss.accept();
    InputStream in=clientSocket.getInputStream();
    //OutputStream out=clientSocket.getOutputStream();
    FileOutputStream fos=new FileOutputStream("b.jpg");
    int x=0;
    while(true){
        x=in.read();
        if(x==-1)break;
        fos.write(x);
    }
    bimg = opencv_highgui.cvLoadImage("b.jpg");
    canvas.showImage(bimg);

  }
}
}

推荐答案

这样想吧...

您有一个生产者,它可以生成图像,您有一个消费者,它想要获取这些图像.

You have a producer, which generates images, you have a consumer, which wants to get those images.

消费者向生产者索要下一张图像,当生产者准备好时,它发送下一张图像,然后消费者以所需的任何方式消费它...

The consumer asks the producer for the next image, when the producer is ready, it sends the next image and the consumer, well, consumes it in what ever manner it wants...

通常,消费者等待生产者生产某些东西,然后对其进行处理,我采取了稍微不同的方向,允许消费者请求"下一个可用的图像.这使得制作人可以继续进行它的快乐,而不会因发送任何可能的内容而陷入困境...

Normally, the consumer waits for the producer to produce something and then processes it, I took a slightly different direction, allowing the consumer to "request" the next available image. This allows the producer to continue on it's merry little way without being bogged down by sending EVERYTHING it can...

为什么要问,因为生成帧可能比通过网络发送帧要快,所以您可以生成丢帧算法,用图像填充队列并让队列管理它愿意缓冲的帧数.然后,生产者"将根据消费者的请求拉出队列的帧并将其发送...

Why you might ask, because generating the frames may be quicker than sending them over the network, this way you could generate a frame dropping algorithm, filling a queue with images and having the queue manage the number of frames it's willing to buffer. The "producer" would then pull frames of the queue at the request of the consumer and send them...

这仅是概念证明,它不涉及多个连接或连接恢复或您需要处理的其他事情

此示例使生产者(服务器)从服务器上的目录发送图像文件.它将根据客户端/消费者的请求继续发送图像,直到没有剩余的图像为止,此时它将发送"NoMoreImages"响应...

This example has the producer (the server), sending images file from a directory on the server. It will keep sending images, at the request of the client/consumer until there are no more images left, at which time it will send the "NoMoreImages" response...

使用者将从服务器请求下一个图像,将其写入磁盘,然后继续操作,直到收到"NoMoreImages"响应为止,然后它将退出...

The consumer will request the next image from the server, write it to disk and continue until it receives the "NoMoreImages" response at which time it will exit...

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class Consumer {

    public static void main(String[] args) {
        System.out.println("Connecting to producer");
        try (Socket socket = new Socket("localhost", 1234)) {

            try (InputStream is = socket.getInputStream();
                            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                            OutputStream os = socket.getOutputStream();
                            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os))) {

                boolean moreImages = true;
                int imageCount = 0;
                do {

                    System.out.println("Requesting next image " + imageCount);
                    writer.write("NextImage");
                    writer.newLine();
                    writer.flush();

                    String response = reader.readLine();
                    System.out.println("Got response " + response);
                    if (response.startsWith("NextImage;")) {

                        String type = response.split(";")[1];
                        String lengthValue = response.split(";")[2];
                        long bytesToBeConsumed = Long.parseLong(lengthValue);
                        try (FileOutputStream fos = new FileOutputStream(new File("Image" + imageCount + "." + type))) {

                            long bytesThatHaveBeenConsumed = 0;
                            int bytesThatWereRead = 0;
                            byte[] buffer = new byte[2048];

                            System.out.println("Reading image of type " + type + " of byte length " + bytesToBeConsumed);

                            while (bytesThatHaveBeenConsumed != bytesToBeConsumed && (bytesThatWereRead = is.read(buffer)) != -1) {

                                bytesThatHaveBeenConsumed += bytesThatWereRead;
                                fos.write(buffer, 0, bytesThatWereRead);

                            }

                            System.out.println("Finished reading image " + imageCount + " with " + bytesThatHaveBeenConsumed + " bytes consumed");

                        }

                        imageCount++;

                    } else if (response.startsWith("NoMoreImages")) {

                        moreImages = false;
                        System.out.println("No more images...");
                        writer.write("Bye");
                        writer.newLine();
                        writer.flush();

                    }

                } while (moreImages);

            }

        } catch (IOException exp) {
            exp.printStackTrace();
        }

        System.out.println("Consumer has left the building...");

    }

}

制作人

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Producer {

    public static void main(String[] args) {

        try (ServerSocket serverSocket = new ServerSocket(1234)) {

            System.out.println("Waiting for connection from consumer...");
            try (Socket socket = serverSocket.accept()) {

                System.out.println("Listing files...");
                File[] images = new File("/some/directory/full/of/images").listFiles(new FileFilter() {
                    @Override
                    public boolean accept(File pathname) {
                        String name = pathname.getName().toLowerCase();
                        return name.endsWith(".gif")
                                        || name.endsWith(".jpeg")
                                        || name.endsWith(".jpg")
                                        || name.endsWith(".png");
                    }
                });

                System.out.println("Have " + images.length);

                int imageIndex = 0;

                try (InputStream is = socket.getInputStream();
                                BufferedReader reader = new BufferedReader(new InputStreamReader(is));
                                OutputStream os = socket.getOutputStream();
                                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os))) {

                    boolean moreRequets = true;

                    do {

                        System.out.println("Waiting for consumer request");
                        String request = reader.readLine();
                        if ("NextImage".equals(request)) {

                            System.out.println("Get next image " + imageIndex);
                            if (images != null && imageIndex < images.length) {

                                File imageFile = images[imageIndex];
                                imageIndex++;

                                long length = imageFile.length();
                                String type = imageFile.getName();
                                type = type.substring(type.lastIndexOf(".") + 1).toLowerCase();

                                String response = new StringBuilder(128).
                                                append("NextImage;").
                                                append(type).
                                                append(";").
                                                append(length).toString();

                                System.out.println("Sending response to consumer " + response);
                                writer.write(response);
                                writer.newLine();
                                writer.flush();

                                System.out.println("Sending file...");
                                try (FileInputStream fis = new FileInputStream(imageFile)) {

                                    byte[] buffer = new byte[2048];
                                    int bytesRead = -1;
                                    while ((bytesRead = fis.read(buffer)) != -1) {

                                        os.write(buffer, 0, bytesRead);

                                    }

                                }

                                System.out.println("File sent...");

                            } else {

                                System.out.println("No more images...");
                                writer.write("NoMoreImages");
                                writer.newLine();
                                writer.flush();

                            }

                        } else if ("Bye".equals(request)) {

                            moreRequets = false;
                            System.out.println("Consumer has left the building...");

                        }

                    } while (moreRequets);

                }

            }

        } catch (IOException exp) {
            exp.printStackTrace();
        }

        System.out.println("Producer has left the building");
    }

}

我不能太强调,这只是一个概念证明,您确实应该考虑拥有一个单独的线程来管理与服务器的传入连接,因此每个客户端都可以独立处理

I can't stress enough, that this is a proof of concept only, you really should consider having a separate thread to manage the incoming connections to the server, so each client can be handled independently.

您不应将套接字管理与GUI管理混合使用,应在单独的线程中进行管理,并且应在主GUI线程的上下文中维护GUI更新.

You should not be mixing your socket management with you GUI management, these should be managed in separate threads and GUI updates should be maintained within the context of the main GUI thread.

这篇关于在Java中的套接字上循环传输时,我只得到一张图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆