我有一个Android应用程序,使用HTML代码将来自摄像机的视频挂在端口8080上。
服务器代码来自foxdog 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尝试下载视频而不显示视频流。
在台式机版本中,我使用此代码加载Web视图,但仅出现一个图像加载失败的空白页面,并且如果我直接在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 Webview的组件,因为我分配的参数无法分配给javafx Webview,或者读取流的任何其他替代方法,尽管它包括更改挂起流的方式。
谢谢你,我等待你的回答