Как я могу посмотреть потоковое видео в веб-обозревателе javafx? - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть приложение Android, которое вешает видео с камеры на порт 8080 с HTML-кодом.

Код сервера от FoxPog Peepers :

/* package */ final class MJpegHttpStreamer
{
private static final String TAG = MJpegHttpStreamer.class.getSimpleName();

private static final String BOUNDARY = "--gc0p4Jq0M2Yt08jU534c0p--";
private static final String BOUNDARY_LINES = "\r\n" + BOUNDARY + "\r\n";

private static final String HTTP_HEADER =
    "HTTP/1.0 200 OK\r\n"
    + "Server: Peepers\r\n"
    + "Connection: close\r\n"
    + "Max-Age: 0\r\n"
    + "Expires: 0\r\n"
    + "Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, "
        + "post-check=0, max-age=0\r\n"
    + "Pragma: no-cache\r\n"
    + "Access-Control-Allow-Origin:*\r\n"
    + "Content-Type: multipart/x-mixed-replace; "
        + "boundary=" + BOUNDARY + "\r\n"
    + BOUNDARY_LINES;

private final int mPort;

private boolean mNewJpeg = false;
private boolean mStreamingBufferA = true;
private final byte[] mBufferA;
private final byte[] mBufferB;
private int mLengthA = Integer.MIN_VALUE;
private int mLengthB = Integer.MIN_VALUE;
private long mTimestampA = Long.MIN_VALUE;
private long mTimestampB = Long.MIN_VALUE;
private final Object mBufferLock = new Object();

private Thread mWorker = null;
private volatile boolean mRunning = false;

/* package */ MJpegHttpStreamer(final int port, final int bufferSize)
{
    super();
    mPort = port;
    mBufferA = new byte[bufferSize];
    mBufferB = new byte[bufferSize];
} // constructor(int, int)

/* package */ void start()
{
    if (mRunning)
    {
        throw new IllegalStateException("MJpegHttpStreamer is already running");
    } // if

    mRunning = true;
    mWorker = new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            workerRun();
        } // run()
    });
    mWorker.start();
} // start()

/* package */ void stop()
{
    if (!mRunning)
    {
        throw new IllegalStateException("MJpegHttpStreamer is already stopped");
    } // if

    mRunning = false;
    mWorker.interrupt();
} // stop()

/* package */ void streamJpeg(final byte[] jpeg, final int length, final long timestamp)
{
    synchronized (mBufferLock)
    {
        final byte[] buffer;
        if (mStreamingBufferA)
        {
            buffer = mBufferB;
            mLengthB = length;
            mTimestampB = timestamp;
        } // if
        else
        {
            buffer = mBufferA;
            mLengthA = length;
            mTimestampA = timestamp;
        } // else
        System.arraycopy(jpeg, 0 /* srcPos */, buffer, 0 /* dstPos */, length);
        mNewJpeg = true;
        mBufferLock.notify();
    } // synchronized
} // streamJpeg(byte[], int, long)

private void workerRun()
{
    while (mRunning)
    {
        try
        {
            acceptAndStream();
        } // try
        catch (final IOException exceptionWhileStreaming)
        {
            System.err.println(exceptionWhileStreaming);
        } // catch
    } // while
} // mainLoop()

private void acceptAndStream() throws IOException
{
    ServerSocket serverSocket = null;
    Socket socket = null;
    DataOutputStream stream = null;

    try
    {
        serverSocket = new ServerSocket(mPort);
        serverSocket.setSoTimeout(1000 /* milliseconds */);

        do
        {
            try
            {
                socket = serverSocket.accept();
            } // try
            catch (final SocketTimeoutException e)
            {
                if (!mRunning)
                {
                    return;
                } // if
            } // catch
        } while (socket == null);

        serverSocket.close();
        serverSocket = null;
        stream = new DataOutputStream(socket.getOutputStream());
        stream.writeBytes(HTTP_HEADER);
        stream.flush();

        while (mRunning)
        {
            final byte[] buffer;
            final int length;
            final long timestamp;

            synchronized (mBufferLock)
            {
                while (!mNewJpeg)
                {
                    try
                    {
                        mBufferLock.wait();
                    } // try
                    catch (final InterruptedException stopMayHaveBeenCalled)
                    {
                        // stop() may have been called
                        return;
                    } // catch
                } // while

                mStreamingBufferA = !mStreamingBufferA;

                if (mStreamingBufferA)
                {
                    buffer = mBufferA;
                    length = mLengthA;
                    timestamp = mTimestampA;
                } // if
                else
                {
                    buffer = mBufferB;
                    length = mLengthB;
                    timestamp = mTimestampB;
                } // else

                mNewJpeg = false;
            } // synchronized

            stream.writeBytes(
                "Content-type: image/jpeg\r\n"
                + "Content-Length: " + length + "\r\n"
                + "X-Timestamp:" + timestamp + "\r\n"
                + "\r\n"
            );
            stream.write(buffer, 0 /* offset */, length);
            stream.writeBytes(BOUNDARY_LINES);
            stream.flush();
        } // while
    } // try
    finally
    {
        if (stream != null)
        {
            try
            {
                stream.close();
            } // try
            catch (final IOException closingStream)
            {
                System.err.println(closingStream);
            } // catch
        } //
        if (socket != null)
        {
            try
            {
                socket.close();
            } // try
            catch (final IOException closingSocket)
            {
                System.err.println(closingSocket);
            } // catch
        } // socket
        if (serverSocket != null)
        {
            try
            {
                serverSocket.close();
            } // try
            catch (final IOException closingServerSocket)
            {
                System.err.println(closingServerSocket);
            } // catch
        } // if
    } // finally
} // accept()


} // class MJpegHttpStreamer

В клиенте Android я вижу его в веб-представлении со следующим кодом:

 private void loadImageInURL(String urlImage) {

    if (myWebView != null) {

        myWebView.getSettings().setJavaScriptEnabled(true);
        myWebView.getSettings().setLoadWithOverviewMode(true);
        myWebView.getSettings().setUseWideViewPort(true);
        // To make the webview transparent to see the background image behind:
        myWebView.setBackgroundColor(0);
        // fit the width of screen
        myWebView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        // remove a weird white line on the right size
        myWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        myWebView.getSettings().setDomStorageEnabled(true);

        myWebView.setInitialScale(50);
        myWebView.setPadding(0, 0, 0, 0);

        int widthScreen = ComActivity.GetInstance().getSizeScreen()[0];

        int heightScreen = ComActivity.GetInstance().getSizeScreen()[1]; 

        this.urlData = "<!DOCTYPE html>" +
                "<html>" +
                        /*
                        "<head>" +
                            "<meta name=\"viewport\" content=\"width=device-width, target-densitydpi=device-dpi, initial-scale=0, maximum-scale=1, user-scalable=yes\">" +
                        "</head>"+
                        */
                "<body style = \"text-align:center\" leftmargin=\"0\" topmargin=\"0\" rightmargin=\"0\" bottommargin=\"0\">" +
                "<img src=http://" + urlImage + "/" + " width=\"" + widthScreen + "px\"  height=\"" + heightScreen + "px\" >" + // Dentro del img> alt="pageNo" width="100%"
                "</body>" +
                "</html>";
        //}


        // en el body --> width="100%"
        // en el meta --> content="width=device-width ...
        ComActivity.GetInstance().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                ComActivity.GetInstance().write("loadDataWithBaseURL ==> urldata =" + urlData);
                myWebView.loadDataWithBaseURL(null, urlData, "text/html", "UTF-8", null);
                myWebView.reload();
            }
        });

    } else {
        Utils.makeToast(ComActivity.GetInstance(), "<WebView> reference in fragment is NULL",Utils.SHORT_TOAST);
    }
}

Теперь я пытаюсь сделать клиент для настольного компьютера с NetBeans и Swing GUI, для этого я использую javafx webView, но в результате видео не загружается.

Я пытался получить доступ к видеоадресу из браузера, и только Chrome корректно загружает изображение, Edge или Explorer пытаются загрузить видео вместо показа видеопотока.

В настольной версии я загружаю свое веб-представление с этим кодом, но получаю только пустую страницу с ошибкой загрузки изображения, и если я помещаю адрес напрямую, как в Chrome, он показывает мне поток как страницу с тегами html затем изображение в виде символов, разделитель изображений в формате html и следующее изображение в символах, пока вы не решите его остановить.

public void setWebView(String string) {

    webViewPanel.removeAll();
    browser = new SwingWebView();
    loadImageInURL(string);
    browser.setBounds(1, 1, webViewPanel.getWidth() - 1, webViewPanel.getHeight() - 1);
    webViewPanel.add(browser, BorderLayout.CENTER);
}

private void loadImageInURL(String urlImage) {

    if (browser != null) {

        int widthScreen = webViewPanel.getWidth();

        int heightScreen = webViewPanel.getHeight();

        this.urlData = "<!DOCTYPE html>"
                + "<html>"
                + "<body style = \"text-align:center\" leftmargin=\"0\" topmargin=\"0\" rightmargin=\"0\" bottommargin=\"0\">"
                + "<img src=http://" + urlImage + "/" + " width=\"" + widthScreen + "px\"  height=\"" + heightScreen + "px\" >"
                + "</body>"
                + "</html>";

        browser.loadURL(urlData); //"http://" + urlImage

    }
}

Класс SwingWebview таков:

public class SwingWebView extends JFXPanel {
private WebEngine engine;

public SwingWebView() {
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            WebView view = new WebView();
            engine = view.getEngine();
            engine.setJavaScriptEnabled(true);
            setScene(new Scene(view));
        }
    });
    setVisible(true);
}

public void loadURL(final String url) {
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            engine.loadContent(url, "text/html"); 

        }
    });
}
}

Я хотел бы знать, если я что-то не так делаю, если html-код для чтения потока неверен, если есть компонент, похожий на веб-представление Android, так как назначаемые параметры не могут быть назначены веб-представлению javafx, или любая другая альтернатива для чтения потока, хотя она включает в себя изменение способа зависания потока.

Спасибо и я жду ваших ответов

...