I have a video stream from an ip-camera and I want to handle this stream via a Server so i can display it on as many devices (like iPads / Browsers) as I need (camera only has 100Mbit/s so a lot of the devices don't show anything). I have a jetty http-Server running. I wrote a class which gets the stream and converts it to a MjpegFrame:
MjpegFrame = frame;
try {
MjpegInputStream m = new MjpegInputStream(url.openStream());
MjpegFrame f;
while ((f = m.readMjpegFrame()) != null) {
if(!running) break;
frame = f;
}
m.close();
} catch (IOException e) {
//some error outputs
}
get the current frame
public MjpegFrame getCurrentFrame() {
return frame;
}
This works fine. Now I am trying to display it with my Servlet, but here I only get a single photo instead of a stream:
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//String auth = request.getAuthType();
//System.out.println("auth:"+auth);
if(vm != null) {
MjpegFrame frame = vm.getCurrentFrame();
if(frame != null) {
BufferedOutputStream output = null;
try{
output = new BufferedOutputStream(response.getOutputStream(), 1024);
response.reset();
response.setBufferSize(1024);
response.setContentType("image/webp");
response.setHeader("Cache-Control", "max-age=0") ;
response.setHeader("Accept-Encoding", "gzip, deflate, sdch");
while(frame != null){
response.setContentLength(frame.getContentLength());
output.write(frame.getJpegBytes(), 0, frame.getContentLength());
frame = vm.getCurrentFrame();
}
}catch(Exception e){
e.printStackTrace();
}finally {
}
} else {
System.out.println("No image available...");
}
} else {
System.out.println("Error: VideoMultiplier is not set");
}
}
Does anyone know what is wrong with my code?
Solved it by myself:
the problem was the Conent-Type
response.setContentType("image/webp");
I used wireshark to analyse it and realised the response should look different. Anyway, thats my response:
String contentType = "multipart/x-mixed-replace; boundary=--yourboundary";
response.setContentType(contentType);
and instead of --yourboundary you use the boundary from the camera, or, to make it more flexible, build your own header:
public StringBuffer createHeader(int contentLength) {
StringBuffer header = new StringBuffer(100);
header.append("--yourboundary\r\nContent-Type: image/jpeg\r\nContent-Length: ");
header.append(contentLength);
header.append("\r\n\r\n");
return header;
}
and then write it like this:
frame = vm.getCurrentFrame();//here I get my frame of the current image I wanna send
StringBuffer header = createHeader(frame.getJpegBytes().length);
byte[] headerBytes = header.toString().getBytes();
byte[] imageBytes = frame.getJpegBytes();
// create a newImage array that is the size of the two arrays
byte[] newImage = new byte[headerBytes.length + imageBytes.length];
// copy headerBytes into start of newImage (from pos 0, copy headerBytes.length bytes)
System.arraycopy(headerBytes, 0, newImage, 0, headerBytes.length);
// copy imageBytes into end of newImage (from pos headerBytes.length, copy imageBytes.length bytes)
System.arraycopy(imageBytes, 0, newImage, headerBytes.length, imageBytes.length);
output.write(newImage,0,newImage.length);
output.flush();
hope it helps someone.
cheers
Related
I'm working on a program that is supposed to display a map with java swing using a google maps api url by given coordinates, my problem is that when i run the code i get this exception:
java.io.IOException: Server returned HTTP response code: 403 for URL
This is my code
public class GoogleMapsDem {
public static void main(String[] args) throws IOException {
JFrame test = new JFrame("Google Maps");
try {
String latitude = "40.714728";
String longitude = "-73.998672";
String imageUrl = "https://maps.googleapis.com/maps/api/staticmap?center=" +
latitude +
"," +
longitude +
"&zoom=11&size=612x612&scale=2&maptype=roadmap&key=YOUR_API_KEY";
String destinationFile = "image.jpg";
// read the map image from Google
// then save it to a local file: image.jpg
//
URL url = new URL(imageUrl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(destinationFile);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
// create a GUI component that loads the image: image.jpg
//
ImageIcon imageIcon = new ImageIcon((new ImageIcon("image.jpg"))
.getImage().getScaledInstance(630, 600,
java.awt.Image.SCALE_SMOOTH));
test.add(new JLabel(imageIcon));
// show the GUI window
test.setVisible(true);
test.pack();
}
}
What could be causing this?
The status code 403 Forbidden represents a client error, which means that the server has the ability to process the request but refuses to authorize access. Simply put, you do not have permission to access this url
static void copyStream(final InputStream inputStream, final OutputStream outputStream, final Client client) throws IOException {
if (client.getReqType() == ReqType.STREAMING_PARTIAL || client.getRange() != null) {
copyPartialStream(inputStream, outputStream, client);
return;
}
Site site = client.getSite();
Qos qos = new Qos(site);
String siteId = site.getSiteId();
byte[] buff = new byte[BUFF_SIZE]; // 1024*32
int readBytes = 0;
try (BufferedInputStream is = new BufferedInputStream(inputStream, BUFF_SIZE)) {
try (BufferedOutputStream out = new BufferedOutputStream(outputStream, BUFF_SIZE)) {
while ((readBytes = is.read(buff)) > -1) {
long startChunk = System.currentTimeMillis();
out.write(buff, 0, readBytes);
client.addSendSize(readBytes);
KHttp.increaseTrafficLog(siteId, readBytes);
long elapsedChunk = System.currentTimeMillis() - startChunk;
client.addSendMils(elapsedChunk);
if (qos.pause(client)) {
long sleepMillis = qos.getSleepMillis(client, readBytes, elapsedChunk);
if (sleepMillis > 0) {
qos.sleep(sleepMillis);
client.addSendMils(sleepMillis);
}
}
}
}
} catch (IOException e) {
client.setAbort(true);
}
}
I am looking at code that provides a link to receive a file using Tomcat. However, if the extension is attached, an error occurs. Not all extensions, but only when the mp3 extension is attached, it is downloaded normally, and when other extensions are attached, an error occurs. It works even if there is no extension at all. I think there is a problem with this code. I hope you can tell me if there is any code with errors. :(
How to I extract form data from a POST request eg. $ curl -X POST -d asdf=blah http://localhost:8000/proxy/http://httpbin.org/post - and I need to extract asdf=blah.
The way I am currently doing it relies heavily on the data I have read being in a certain format (I am assuming the form data is always on the last line). Is there a better (and/or simpler) way to get the data which does not depend on the format of the data being read ?
(Note: the proxy deals with both GET and POST requests)
Here is code I have written :
public class ProxyThread3 extends Thread {
private Socket clientSocket = null;
private OutputStream clientOutputStream;
private static final int BUFFER_SIZE = 32768;
public ProxyThread3(Socket socket) {
super("ProxyThread");
this.clientSocket = socket;
}
public void run() {
try {
clientOutputStream = clientSocket.getOutputStream();
// Read request
InputStream clientInputStream = clientSocket.getInputStream();
byte[] b = new byte[8196];
int len = clientInputStream.read(b);
String urlToCall = "";
if (len > 0) {
String userData = new String(b, 0, len);
String[] userDataArray = userData.split("\n");
//Parse first line to get URL
String firstLine = userDataArray[0];
for (int i = 0; i < firstLine.length(); i++) {
if (firstLine.substring(i).startsWith("http://")) {
urlToCall = firstLine.substring(i).split(" ")[0];
break;
}
}
//get request type
String requestType = firstLine.split(" ")[0];
String userAgentHeader = "";
//get USER-AGENT Header and Accept Header
for (String data : userDataArray) {
if (data.startsWith("User-Agent")) {
userAgentHeader = data.split(":")[1].trim();
break;
}
}
switch (requestType) {
case "GET": {
sendGetRequest(urlToCall, userAgentHeader);
break;
}
case "POST": {
String postParams = null;
//Get Form Data
if (!userDataArray[userDataArray.length - 1].isEmpty()) {
postParams = userDataArray[userDataArray.length - 1];
}
sendPostRequest(urlToCall, userAgentHeader, postParams);
break;
}
}
} else {
clientInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void sendPostRequest(String urlToCall, String userAgentHeader, String postParams) throws IOException {
URL urlToWriteAndReadFrom = new URL(urlToCall);
HttpURLConnection httpURLConnection = (HttpURLConnection) urlToWriteAndReadFrom.openConnection();
httpURLConnection.setRequestMethod("POST");
// set User-Agent header
httpURLConnection.setRequestProperty("User-Agent", userAgentHeader);
httpURLConnection.setDoOutput(true);
OutputStream urlOutputStream = httpURLConnection.getOutputStream();
if (postParams != null) {
urlOutputStream.write(postParams.getBytes());
urlOutputStream.flush();
}
urlOutputStream.close();
int responseCode = httpURLConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // success
InputStream dataReader = httpURLConnection.getInputStream();
//begin send response to client
byte inputInBytes[] = new byte[BUFFER_SIZE];
assert dataReader != null;
int index = dataReader.read(inputInBytes, 0, BUFFER_SIZE);
while (index != -1) {
clientOutputStream.write(inputInBytes, 0, index);
index = dataReader.read(inputInBytes, 0, BUFFER_SIZE);
}
clientOutputStream.flush();
}
}
private void sendGetRequest(String urlToCall, String userAgentHeader) throws IOException {
URL urlToReadFrom = new URL(urlToCall);
HttpURLConnection httpURLConnection = (HttpURLConnection) urlToReadFrom.openConnection();
// set True since reading and getting input
httpURLConnection.setDoInput(true);
httpURLConnection.setRequestMethod("GET");
// set User-Agent header
httpURLConnection.setRequestProperty("User-Agent", userAgentHeader);
int responseCode = httpURLConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) { // success
InputStream dataReader = httpURLConnection.getInputStream();
//begin send response to client
byte inputInBytes[] = new byte[BUFFER_SIZE];
assert dataReader != null;
int index = dataReader.read(inputInBytes, 0, BUFFER_SIZE);
while (index != -1) {
clientOutputStream.write(inputInBytes, 0, index);
index = dataReader.read(inputInBytes, 0, BUFFER_SIZE);
}
clientOutputStream.flush();
}
}
}
PS. I am new to all of this so if there are any errors in my code, please do point them out
Here is a full example on how to create a Java HTTP server that handles POST and GET requests.
https://www.codeproject.com/Tips/1040097/Create-a-Simple-Web-Server-in-Java-HTTP-Server
That being shared, this is quite primitive, I'd recommend using any third party library or light-weight Java server like Grizzly or Jetty if not a server like Apache Tomcat utilizing J2EE Servlets which are made for this purpose.
i write simple applet to download file from HTTP URL.
In Eclipse or Netbeans, it 's work well and can download file to d://abc//123.iso on my HDD.
This is my code :
public class download {
public static void saveUrl(final String filename, final String urlString)
throws MalformedURLException, IOException {
BufferedInputStream in = null;
FileOutputStream fout = null;
try {
in = new BufferedInputStream(new URL(urlString).openStream());
fout = new FileOutputStream(filename,true);
final byte data[] = new byte[1024];
int count;
fout.write(data, 0, count);
} finally {
if (in != null) {
in.close();
}
if (fout != null) {
fout.close();
}
}
}
}
public class HelloWorldApplet extends Applet
{
public void paint (Graphics g)
{
g.drawString ("Download file", 25, 50);
String url ="http://downloads.asterisk.org/pub/telephony/asterisk-now/AsteriskNOW-612-current-32.iso";
String file_out = "d:\\abc\\123.iso";
download.saveUrl(file_out, url);
}
}
==========================
But when export to jar file and run with html, browser can creat new file 123.iso on my HDD but the size of this file is always 2 Kbps. i think it do not download anything.
Please help me
Thanks so much
P/s : i try to sign jar file with jarsigner but it does not solve the problem
Although I'm skeptical as to the code above doing anything at all as posted, if even compiling, here's the solution I use for doing automatic update downloads of large (>100 MB) files:
HttpGet httpGet;
RequestConfig requestConfig;
getProxySettings();
//Check to see if there is a proxy availabble.
if (!LicensePreloader.proxyAddr.equals("")) {
requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.setProxy(new HttpHost(LicensePreloader.proxyAddr, LicensePreloader.proxyPort))
.build();
} else {
//No proxy was available, just use regular internet.
requestConfig = RequestConfig.custom()
.setSocketTimeout(5000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(5000)
.build();
}
httpGet = new HttpGet(this.remoteUrl);
HttpResponse response;
InputStream remoteContentStream = null;
OutputStream localFileStream = null;
try {
httpGet.setConfig(requestConfig);
response = httpClient.execute(httpGet);
//This builds the content of our file we're downloading.
remoteContentStream = response.getEntity().getContent();
long fileSize = response.getEntity().getContentLength();
File dir = localFile.getParentFile();
dir.mkdirs();
localFileStream = new FileOutputStream(localFile);
//Set the buffer, in our use case, it's always the deafult 8192 bytes.
byte[] buffer = new byte[bufferSize];
int sizeOfChunk;
int amountComplete = 0;
//Simply loop through and download the file in 'chunks'
while ((sizeOfChunk = remoteContentStream.read(buffer)) != -1) {
localFileStream.write(buffer, 0, sizeOfChunk);
amountComplete += sizeOfChunk;
updateProgress(amountComplete, fileSize);
}
return localFile;
} finally {
//Make sure to clean everything up.
try {
if (remoteContentStream != null) {
remoteContentStream.close();
}
if (localFileStream != null) {
localFileStream.close();
}
} catch (IOException ex) {
//If we're here, it's likely because the internet conneciton
//couldn't be established, or it was cut short in the middle.
ex.printStackTrace(System.out);
failed();
}
}
}
This is obviously overkill for your application, and you can probably just forget all the proxy business, but I kept it in there for completeness sake. There are a couple helper methods I didn't include, but again, they're almost all exclusively for proxy handling.
good luck!
You are writing one the first read in the input. You need to write the file until the input is empty.
Try this while in you code
while ((count = in.read(data)) != -1) {
fout.write(data, 0, count);
...
}
Can someone please give me a hand with this image downloading code? I want it to run in the background, but it seems like new Thread(new Runnable()) is definitely not the way to go, according to the Android docs, and I'm not sure how else to approach this:
// caller
while( exhibitorCursor.moveToNext() )
{
new Thread(new Runnable()
{
public void run()
{
downloadImage(exhibitorId, exhibitorString, DOWNLOAD_EXHIBITOR);
}
}).start();
}
// first function
public void downloadImage(long id, String externalImageUrl, int type)
{
// logic junk here
if( !(new File(localImageName).exists()) )
{
DownloadFromUrl(externalImageUrl, localImageName);
}
}
// second function
public void DownloadFromUrl(String fileUrl, String fileName)
{
// this is the downloader method
try
{
URL url = new URL(fileUrl);
File file = new File(fileName);
URLConnection ucon = url.openConnection();
InputStream is = ucon.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is, 8192);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while( (current = bis.read()) != -1 )
{
baf.append((byte)current);
}
/* Convert the Bytes read to a String. */
FileOutputStream fos = new FileOutputStream(file);
fos.write(baf.toByteArray());
fos.close();
}
catch( IOException e )
{
Log.d("ImageManager", "Error: " + e);
}
}
Is there a less painful way of doing this? I'm only downloading like 20 images to use later in the app, and it is locking it up right away.
It may not be relevant, but this is how I am achieving it in Obj-C for the iPhone version.
for( NSDictionary *exhibitor in exhibitors )
{
[self performSelectorInBackground:#selector(downloadExhibitorImage:) withObject:exhibitor];
}
Take a look at the DownloadManager and as an alternative at AsyncTask