This question already has an answer here:
How to Merge Multiple MP4 Videos files in single file
(1 answer)
Closed 3 years ago.
Could someone please tell me what is wrong in the below code, I'm trying to merge two different video URLs to same file, (both videos have the same size 1024x720)
String url1 = "https://test.com/vid1";
String url2 = "https://test.com/vid2";
FileOutputStream out = new FileOutputStream(new File("test.mp4"));
writeToFile(url1, out);
writeToFile(url2, out);
out.close();
//Even tried the below way of first saving one file and then opening the same file to append the stream data
/*
FileOutputStream out = new FileOutputStream(new File("test.mp4"));
writeToFile(url1, out);
out.close();
out = new FileOutputStream(new File("test.mp4"), true);
writeToFile(url2, out);
out.close();
*/
void writeToFile(String url, FileOutputStream out) {
HttpsURLConnection con = (HttpsURLConnection) new URL(url).openConnection();
con.setRequestMethod("GET");
BufferedInputStream bis = new BufferedInputStream(con.getInputStream());
int count;
byte buf[] = new byte[20480];
while((count = bis.read(buf, 0, 20480)) != -1)
out.write(buf, 0, count);
bis.close();
con.disconnect();
}
I have tried to save the file using the above two methods but both create only one video file i.e., the second video is not appended (i'm able to save both files if given different names)
The problem is replacing the content of file and not concat.
the function FileOutputStream(File file, boolean append) use second parameter for this purpose. use this method with true value for the second parameter
To concatenate two videos you need special software. ffmpeg is one:
ffmpeg -i vid-1.mp4 -i vid-2.mp4 -filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" all.mp4
If you want to play the combined video. If you only need to store the info, your usual way should work.
Related
This question already has answers here:
Easy way to write contents of a Java InputStream to an OutputStream
(24 answers)
Closed 6 years ago.
Part filePart = request.getPart("barcodePhtotoVen");
inputStream = filePart.getInputStream();
How to write this using outputstream to folder/file in my computer drive?
Hope following code snippet help you
Update :
OutputStream out = null;
InputStream filecontent = null;
try {
out = new FileOutputStream(new File("destination_file_path"));
filecontent = filePart.getInputStream();
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = filecontent.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
} catch (FileNotFoundException f) {
} finally {
if (out != null) {
out.close();
}
}
Earlier code I tested on mine system, perfectly worked. Please try mine updated code. I just tested on mine system and its working fine too.
Resources : Hope this knowledge sharing help you.
Thanks.
Do not use an InputStream and do not use an OutputStream. Part has a write(String) method which writes the part directly to a file.
I have stored image to inputstream
No you haven't. You haven't stored the image anywhere, let alone to an input stream, which is a contradiction in terms. You need to read from the input stream and write to a disk file.
For a class, I have to send a file of any type from my client to a server. I have to handle each packet individually and use UDP. I have managed to transfer the file from the client to the server, and I now have a file object which I cannot figure out how to save to a user specified directory.
f = new File(path + '\\' + filename);//path and filename are user specified.
FileOutputStream foutput = new FileOutputStream(f);
ObjectOutputStream output = new ObjectOutputStream(foutput);
output.writeObject(result);//result is a File
output.flush();
output.close();
Any time I run this code, it writes a new file with the appropriate name, but the text file I am testing ends up just containing gibberish. Is there any way to convert the File object to a file in the appropriate directory?
EDIT: As it turns out, I was misunderstanding what, exactly, a file is. I have not been transferring the data, but rather the path. How do I transfer an actual file?
ObjectOutputStream is a class that outputs a specific format of data to a text file. Only ObjectInputStream's readObject() can decoding that text file.
If you open the text file , it is just gibberish ,as you have seen.
you want this:
FileOutputStream fos = new FileOutputStream(path + '\\' + filename);
FileInputStream fis = new FileInputStream(result);
byte[] buf = new byte[1024];
int hasRead = 0;
while((hasRead = fis.read(buf)) > 0){
fos.write(buf, 0, hasRead);
}
fis.close();
fos.close();
If I understand your question, how about using a FileWriter?
File result = new File("result.txt");
result.createNewFile();
FileWriter writer = new FileWriter(result);
writer.write("Hello user3821496\n"); //just an example how you can write a String to it
writer.flush();
writer.close();
In the end, my ultimate goals are:
Read from a URL (what this question is about)
Save the retrieved [PDF] content to a BLOB field in a DB (already have that nailed down)
Read from the BLOB field and attach that content to an email
All without going to a filesystem
The goal with the following method is to get a byte[] that can be used downstream as an email attachment (to avoid writing to disk):
public byte[] retrievePDF() {
HttpClient httpClient = new HttpClient();
GetMethod httpGet = new GetMethod("http://website/document.pdf");
httpClient.executeMethod(httpGet);
InputStream is = httpGet.getResponseBodyAsStream();
byte[] byteArray = new byte[(int) httpGet.getResponseContentLength()];
is.read(byteArray, 0, byteArray.length);
return byteArray;
}
For a particular PDF, the getResponseContentLength() method returns 101,689 as the length. The strange part is that if I set a break-point and interrogate the byteArray variable, it has 101,689 byte elements, however, after byte #3744 the remaining bytes of the array are all zeroes (0). The resulting PDF is then not readable by a PDF-reader client, like Adobe Reader.
Why would that happen?
Retrieving this same PDF via browser and saving to disk, or using a method like the following (which I patterned after an answer to this StackOverflow post), results in a readable PDF:
public void retrievePDF() {
FileOutputStream fos = null;
URL url;
ReadableByteChannel rbc = null;
url = new URL("http://website/document.pdf");
DataSource urlDataSource = new URLDataSource(url);
/* Open a connection, then set appropriate time-out values */
URLConnection conn = url.openConnection();
conn.setConnectTimeout(120000);
conn.setReadTimeout(120000);
rbc = Channels.newChannel(conn.getInputStream());
String filePath = "C:\\temp\\";
String fileName = "testing1234.pdf";
String tempFileName = filePath + fileName;
fos = new FileOutputStream(tempFileName);
fos.getChannel().transferFrom(rbc, 0, 1 << 24);
fos.flush();
/* Clean-up everything */
fos.close();
rbc.close();
}
For both approaches, the size of the resulting PDF is 101,689-bytes when doing a Right-click > Properties... in Windows.
Why would the byte array essentially "stop" part-way through?
InputStream.read reads up to byteArray.length bytes but might not read exactly that much. It returns how many bytes it read. You should call it repeatedly to fully read the data, like this:
int bytesRead = 0;
while (true) {
int n = is.read(byteArray, bytesRead, byteArray.length);
if (n == -1) break;
bytesRead += n;
}
Check the return value of InputStream.read. It's not going to read all at one go. You have to write a loop. Or, better yet, use Apache Commons IO to copy the stream.
101689 = 2^16 + 36153 so it would look like, that there is a 16 bit limitation on buffer size.
The difference between 36153 and 3744 maybe stems from the header part having been read in an extra small 1K buffer or so, and already containing some bytes.
Hello Stack Overflow community,
I am doing multistep processing on some data I am receiving with a java Servlet. The current process I have is that I input the files to a server using Apache File Upload and convert them to a File. Then once input1 is populated with data, I run through a flow similar to this (where the process functions are xsl transforms):
File input1 = new File(FILE_NAME); // <---this is populated with data
File output1 = new File(TEMP_FILE); // <---this is the temporary file
InputStream read = new FileInputStream(input1);
OuputStream out = new FileOutputStream(output1);
process1ThatReadsProcessesOutputs( read, out);
out.close();
read.close();
//this is basically a repeat of the above process!
File output2 = new File(RESULT_FILE); // <--- This is the result file
InputStream read1 = new FileInputStream(output1);
OutputStream out1 = new FileOutputStream(output2);
Process2ThatReadsProcessesOutputs( read1, out1);
read1.close();
out1.close();
…
So my question is if there is a better way to do this so I do not have to create those temporary Files and recreate streams to those Files? (I am assuming I am incurring a decent performace penatly)
I saw this Most Efficient Way to create InputStream from OutputStream but I am not sure if this is the best route to go...
Just replace FileOutputStream to ByteArrayInputStream vice/versa.
Example:
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
I don't know why are you converting the FileItem retrieved with Apache Commons if you don't really needed. You can use the same InputStream that each FileItem has to using and read the content of the uploaded file:
// create/retrieve a new file upload handler
ServletFileUpload upload = ...;
// parse the request
List<FileItem> items = (List<FileItem>) upload.parseRequest(request);
/* get the FileItem from the List. Yes, it's not a best practice because you must verify
how many you receive, and check everything is ok, etc.
Let's suppose you've done it */
//...
FileItem item = items.get(0);
// get the InputStrem to read the contents of the file
InputStream is = item.getInputStream();
So finally, you can use the InputStream object to read the uploaded stream sent by the client avoiding unnecessary instantiations.
And yes, it's really recommended to use Buffered clases like BufferedInputStream and BufferedOutputStream.
The other idea could be to avoid FileOutputStream (the middle one) and replace it with ByteArrayOutputStream if you don't need to be written in disk (always is slower than working in memory).
Java 9 brings a new answer to the question:
// All bytes from an InputStream at once
byte[] result = new ByteArrayInputStream(buf)
.readAllBytes();
// Directly redirect an InputStream to an OutputStream
new ByteArrayInputStream(buf)
.transferTo(System.out);
I have a simple question. I'm trying to upload a file to my ftp server in Java.
I have a file on my computer, and I want to make a copy of that file and upload it. I tried manually writing each byte of the file to the output stream, but that doesn't work for complicated files, like zip files or pdf files.
File file = some file on my computer;
String name = file.getName();
URL url = new URL("ftp://user:password#domain.com/" + name +";type=i");
URLConnection urlc = url.openConnection();
OutputStream os = urlc.getOutputStream();
//then what do I do?
Just for kicks, here is what I tried to do:
OutputStream os = urlc.getOutputStream();
BufferedReader br = new BufferedReader(new FileReader(file));
String line = br.readLine();
while(line != null && (!line.equals(""))) {
os.write(line.getBytes());
os.write("\n".getBytes());
line = br.readLine();
}
os.close();
For example, when I do this with a pdf and then try and open the pdf that I run with this program, it says an error occurred when trying to open the pdf. I'm guessing because I am writing a "\n" to the file? How do I copy the file without doing this?
Do not use any of the Reader or Writer classes when you're trying to copy the byte-for-byte exact contents of a binary file. Use these only for plain text! Instead, use the InputStream and OutputStream classes; they do not interpret the data at all, while the Reader and Writer classes interpret the data as characters. For example
OutputStream os = urlc.getOutputStream();
FileInputStreamReader fis = new FileInputStream(file);
byte[] buffer = new byte[1000];
int count = 0;
while((count = fis.read(buffer)) > 0) {
os.write(buffer, 0, count);
}
Whether your URLConnection usage is correct here, I don't know; using Apache Commons FTP (as suggested elsewhere) would be an excellent idea. Regardless, this would be the way to read the file.
Use a BufferedInputStream to read and BufferedOutputStream to write. Take a look at this post: http://www.ajaxapp.com/2009/02/21/a-simple-java-ftp-connection-file-download-and-upload/
InputStream is = new FileInputStream(localfilename);
BufferedInputStream bis = new BufferedInputStream(is);
OutputStream os =m_client.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
int readCount;
while( (readCount = bis.read(buffer)) > 0) {
bos.write(buffer, 0, readCount);
}
bos.close();
FTP usually opens another connection for data transfer.
So I am not convinced that this approach with URLConnection is going
to work.
I highly recommend that you use specialized ftp client. Apache commons
may have one.
Check this out
http://commons.apache.org/net/api/org/apache/commons/net/ftp/FTPClient.html