These two days I have been working on setting up the FLV video environment, including Server Installation and Java applications. There is no major problem in installing FFMPEG and mencoder, but there is still a small problem that makes me depressed, that is, an error occurs when installing amrwb and amrnb. The error is as follows:
/Usr/bin/wget-N http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-610.zip
-- 20:41:59 -- http://www.3gpp.org/ftp/Specs/archive/26_series/26.104/26104-610.zip
Parsing host www.3gpp.org... 212.234.161.21
Connecting to www.3gpp.org | 212.234.161.21 |: 80... connected.
An HTTP request has been sent and is waiting for response... 403 Forbidden
20:42:00 error 403: forbidden.
Make: *** invalid 26104-610.zip] Error 1
Later, I carefully read and asked the company's network administrator to know that I did not open the Internet for this test machine. I also thought of this problem at the beginning. I can ping it when I can ping it, so I gave up that idea. Who knows this is really the problem? The result is just a bit simple. After activating the network, the installation will be very smooth ~~~ This is an out-of-the-box question.
After the FFMPEG environment is set up, it is no problem to manually convert it locally. It is no problem to call the program (without obtaining the program feedback results. Later, when I submitted a video conversion request, I had to perform database operations. For example, before the conversion, I updated the status of the video to being updated, after the conversion, enter the FLV file path and image path information of the video, as well as the size and duration of the FLV file. This requires controlling the status of the FFMPEG process in the thread. here we need to use the process class. The typical code is as follows:
......
Process = runtime.getruntime.exe C (CMD); // run the FFMPEG command
Inputstream is = process. getinputstream (); // gets the output stream of the FFMPEG Process
Bufferedreader BR = new buffered (New inputstreamreader (is); // buffer read
Stringbuilder Buf = new stringbuilder (); // Save the output stream of FFMPEG
String line = NULL;
While (line = Br. Readline ())! = NULL) BUF. append (line); // The loop waits until the FFMPEG process ends.
System. Out. println ("FFMPEG output content:" + BUF );
......
This is usually the way to call a program and get the output stream of the process. However, when I execute such a call on Windows, it is always blocked while, as a result, the FFMPEG program will not be executed after being executed for a while. here we can see from the official reference documents that this is due to the buffer issue because the Java Process has not cleared the content written by the FFMPEG program to the buffer, as a result, the FFMPEG program remains waiting. I also found a lot of such problems on the Internet, but all I said was to use a separate thread for control. I also tried a lot of methods on the Internet, but it never worked. The following is my solution. Have you noticed the red part in the above Code? Here is the key. I changed it to the following result and it will run normally.
Inputstream is = process. geterrorstream (); // gets the output stream of the FFMPEG Process
Did you notice? I changed it to get the error stream so that the process will not be blocked, and I have been thinking that the same command can be completed when I call it manually, java calls cannot be completed. It is always considered that the buffer zone of getinputstream is not cleared, but the problem is that the buffer content is not cleared, but not the buffer of getinputstream, but the buffer zone of geterrorstream, in this way, the problem is solved. Therefore, when we encounter thread blocking caused by Java calling external programs, we can consider using two threads to clear the two input streams obtained by process at the same time, as shown below:
......
Process = runtime.getruntime.exe C (command); // call an external program
Final inputstream is1 = process. getinputstream ();
New thread (New runnable (){
Public void run (){
Bufferedreader BR = new buffered (New inputstreamreader (is ));
While (Br. Readline ()! = NULL );
}
}. Start (); // start a separate thread to clear the buffer zone of process. getinputstream ().
Inputstream is2 = process. geterrorstream ();
Bufferedreader Br2 = new buffered (New inputstreamreader (is2 ));
Stringbuilder Buf = new stringbuilder (); // Save the output result stream
String line = NULL;
While (line = Br. Readline ())! = NULL) BUF. append (line); // The loop waits until the FFMPEG process ends.
System. Out. println ("output result:" + BUF );
......
In this way, we use a thread to read the process. the output stream of getinputstream (). Use another thread to obtain the process. the output stream of geterrorstream (), so that we can ensure that the buffer is cleared in time without worrying about thread blocking. Of course, you can retain the content in the process. getinputstream () stream as needed. It depends on the processing of the called program. In Windows, when I call the FFMPEG program for video conversion, this solves the problem of thread congestion ~
So I think it's like process. getinputstream and process. the geterrorstream methods are not really represented by the name. One is to get the normal output of the called program, and the other is to get the error stream of the called program. Sometimes the error stream (errorstream) is also the normal output of the program, because after all, Java calls such a program in Windows and Linux, so we should open our mind When writing the program, what we take for granted is not necessarily true!