I am trying to download video from RTSP stream to a file on my computer using the Xuggler 5.4 library.
String outputFilename = "D:\\downloadedrtsp.avi";
String inputSource = "rtsp://[ip-address]:[port]/user=[username]&[password]=password&channel=1&stream=1.sdp";
try {
IContainer container = IContainer.make();
IMetaData im = IMetaData.make();
im.setValue("max_delay", (1000000l) + "");
int retval = im.setValue("rtsp_transport", "tcp");
container.open(inputSource, IContainer.Type.READ, null, false, true, im, null);
IMediaReader mediaReader = ToolFactory.makeReader(container);
IMediaWriter mediaWriter = ToolFactory.makeWriter(outputFilename, mediaReader);
mediaReader.addListener(mediaWriter);
IError error;
while ((error = mediaReader.readPacket()) == null) {
logger.info("reading packet");
}
} catch (Exception e) {
e.printStackTrace();
}
But the code fails with a stacktrace
15:40:52.500 [main] ERROR org.ffmpeg - [tcp # 00000000171C6BE0] Failed to resolve hostname \downloadedrtsp.avi: ???? ???? ??????????.
15:40:52.500 [main] ERROR com.xuggle.xuggler - Error: could not write header for container (../../../../../../../csrc/com/xuggle/xuggler/Container.cpp:827)
java.lang.RuntimeException: Error Operation not permitted, failed to write header to container com.xuggle.xuggler.IContainer#387681280[url:D:\downloadedrtsp.avi;type:WRITE;format:com.xuggle.xuggler.IContainerFormat#387719536[oname:rtsp;olongname:RTSP output format;omimetype:null;oextensions:null;];] while establishing stream com.xuggle.xuggler.IStream#387690704[index:1;id:0;streamcoder:com.xuggle.xuggler.IStreamCoder#384527536[codec=com.xuggle.xuggler.ICodec#387719392[type=CODEC_TYPE_AUDIO;id=CODEC_ID_AAC;name=libvo_aacenc;];time base=1/8000;frame rate=0/0;sample rate=8000;channels=1;];framerate:0/0;timebase:1/90000;direction:OUTBOUND;]
at com.xuggle.mediatool.MediaWriter.getStream(MediaWriter.java:1058)
at com.xuggle.mediatool.MediaWriter.encodeAudio(MediaWriter.java:830)
at com.xuggle.mediatool.MediaWriter.onAudioSamples(MediaWriter.java:1441)
at com.xuggle.mediatool.AMediaToolMixin.onAudioSamples(AMediaToolMixin.java:89)
at com.xuggle.mediatool.MediaReader.dispatchAudioSamples(MediaReader.java:628)
at com.xuggle.mediatool.MediaReader.decodeAudio(MediaReader.java:555)
at com.xuggle.mediatool.MediaReader.readPacket(MediaReader.java:469)
at ua.datalink.main.StreamTranscodingExample.readHigherLevel(StreamTranscodingExample.java:103)
at ua.datalink.main.StreamTranscodingExample.main(StreamTranscodingExample.java:121)
The file is created on program startup, but it's empty. Where can the problem lies? I have spend hours to figure it out, but still no result.
Related
I am using Jpedal tool to convert PDF to Image.
When PDF pages are very large in number and we process it to convert then tomcat gets stopped and throws Exception-
javax.imageio.IIOException: I/O error writing PNG file.
Can anyone please help for this.
public boolean createPDF2ImageTask(String sourcePDFAbsPath, String destinationImageAbsPath, Float scalingFactor, String fileFormat, int softLimitInKB) throws Exception
{
System.setProperty("org.jpedal.flattenForm","true");
logger.info("createPDF2ImageTask ( sourcePDFAbsPath = "+sourcePDFAbsPath+" , destinationImageAbsPath = "+destinationImageAbsPath+ ", scalingFactor = "+scalingFactor+ " , fileFormat = "+fileFormat+ " softLimitInKB ="+softLimitInKB );
boolean status = true;
Float newScalingFactor;
int sizeOfImageInKB;
//PdfDecoder object provides the conversion
PdfDecoderServer decoder = null;
Map mapValues = null;
BufferedImage imageToSave = null;
BufferedOutputStream bufferedOutputStream = null;
long startTime = System.currentTimeMillis();
try
{
Helper.deleteFile(destinationImageAbsPath);
//mappings for non-embedded fonts to use
FontMappings.setFontReplacements();
decoder = new PdfDecoderServer(true);
decoder.openPdfFile(sourcePDFAbsPath);
mapValues = new HashMap();
mapValues.put(JPedalSettings.EXTRACT_AT_BEST_QUALITY_MAXSCALING, 2);
//alternatively secify a page size (aspect ratio preserved so will do best fit)
//set a page size (JPedal will put best fit to this)
PdfPageData pageData = decoder.getPdfPageData();
int width = (int)(scalingFactor*pageData.getCropBoxWidth(1));
int height = (int)(scalingFactor*pageData.getCropBoxHeight(1));
logger.info("width = "+ width + " height= "+height);
mapValues.put(JPedalSettings.EXTRACT_AT_PAGE_SIZE, new String[]{String.valueOf(width),String.valueOf(height)});
//which takes priority (default is false)
mapValues.put(JPedalSettings.PAGE_SIZE_OVERRIDES_IMAGE, Boolean.TRUE);
PdfDecoderServer.modifyJPedalParameters(mapValues);
/////////////////////////////////////////////////////////////////////////////////////
try
{
imageToSave = decoder.getPageAsHiRes(1, null, false);
decoder.flushObjectValues(true);
if(imageToSave != null)
{
logger.info("Start saving image as a file");
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(new File(destinationImageAbsPath)));
ImageIO.write(imageToSave, fileFormat, bufferedOutputStream);
}
else
{
throw new Exception("imageToSave is null, Exception in extractPageAsImage ");
}
}
catch(Exception e)
{
logger.error("Exception in extractPageAsImage :: "+e);
logger.error("Exception stack trace in extractPageAsImage :: ",e);
throw new Exception("Exception in extractPageAsImage :: "+e);
}
It's throwing Exception - Exception in extractPageAsImage :: javax.imageio.IIOException: I/O error writing PNG file!
Maybe you could try to solve this by increasing memory of your Tomcat instance. On Unix platforms this can be achieved by adding some Java options in setenv.sh:
export JAVA_OPTS="$JAVA_OPTS -Xms128m -Xmx2048m -XX:MaxPermSize=512m"
or on Windows in the file setenv.bat:
set "JAVA_OPTS=%JAVA_OPTS% -Xms128m -Xmx2048m -XX:MaxPermSize=512m"
Please note that the numbers in the examples above are just examples, as they depend on the memory available on your platform.
Please refer to Tomcat's RUNNING.txt for further details on how to configure the Tomcat on your platform.
I am trying to download a video (with a Xuggler 5.4 library) from rtsp stream to a file using the code below.
String inputSource = "rtsp://[ip-address]:[port]/user=[username]&[password]=password&channel=1&stream=1.sdp";
String outputFilename = "d:/downloadedrtsp.flv";
try {
IContainerFormat inFormat = IContainerFormat.make();
inFormat.setInputFormat("h246");
IMediaReader mediaReader = ToolFactory.makeReader(inputSource);
mediaReader.setQueryMetaData(false);
IMediaWriter mediaWriter = ToolFactory.makeWriter(outputFilename, mediaReader);
mediaReader.addListener(mediaWriter);
logger.info("before reading");
IError error;
while ((error = mediaReader.readPacket()) == null) {
logger.info("reading packet");
}
logger.info("error: " + error.getDescription());
logger.info(error.getType());
logger.info(error.toString());
} catch (Exception e) {
e.printStackTrace();
}
The problem is that after printing "before reading" the code just stop executing, and after a long time it prints me three lines from logger:
error: Unknown error
ERROR_EOF
Unknown error
Stream works great when i am opening it in the VLC media player. I am shure there is some mistake in my mediaReader configuration, but i don't know where exactly as i have a very little experience working with videos. Here is some information about video, taken from VLC:
It seems like everything works as expected.
The error type ERROR_EOF marks the end of the input stream (see the documentation).
The long time you program "stop executing" is the time it takes for Xuggler to convert the video frames (it actually doesn't "stop", just iterate through the while loop).
I work on a sample java http server and a .Net client (on tablet).
using my http sever, the .Net client must be able to download files.
It's working perfectly, but now I have to be able to resume download after a connection disruption.
Here some code :
Java server : ( It is launched in a seperate thread, hence the run method).
public void run() {
try {
server = com.sun.net.httpserver.HttpServer.create(
new InetSocketAddress(
portNumber), this.maximumConnexion);
server.setExecutor(executor);
server.createContext("/", new ConnectionHandler(this.rootPath));
server.start();
} catch (IOException e1) {
//For debugging
e1.printStackTrace();
}
}
my HttpHandler : (only the part dealing with GET request)
/**
* handleGetMethod : handle GET request. If the file specified in the URI is
* available, send it to the client.
*
* #param httpExchange
* #throws IOException
*/
private void handleGetMethod(HttpExchange httpExchange) throws IOException {
File file = new File(this.rootPath + this.fileRef).getCanonicalFile();
if (!file.isFile()) {
this.handleError(httpExchange, 404);
} else if (!file.getPath().startsWith(this.rootPath.replace('/', '\\'))) { // windows work with anti-slash!
// Suspected path traversal attack.
System.out.println(file.getPath());
this.handleError(httpExchange, 403);
} else {
//Send the document.
httpExchange.sendResponseHeaders(200, file.length());
System.out.println("file length : "+ file.length() + " bytes.");
OutputStream os = httpExchange.getResponseBody();
FileInputStream fs = new FileInputStream(file);
final byte[] buffer = new byte[1024];
int count = 0;
while ((count = fs.read(buffer)) >= 0) {
os.write(buffer, 0, count);
}
os.flush();
fs.close();
os.close();
}
}
And now my .Net Client: (simplified)
try{
Stream response = await httpClient.GetStreamAsync(URI + this.fileToDownload.Text);
FileSavePicker savePicker = new FileSavePicker();
savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
// Dropdown of file types the user can save the file as
savePicker.FileTypeChoices.Add("Application/pdf", new List<string>() { ".pdf" });
// Default file name if the user does not type one in or select a file to replace
savePicker.SuggestedFileName = "new doc";
StorageFile file = await savePicker.PickSaveFileAsync();
if (file != null)
{
const int BUFFER_SIZE = 1024*1024;
using (Stream outputFileStream = await file.OpenStreamForWriteAsync())
{
using (response)
{
var buffer = new byte[BUFFER_SIZE];
int bytesRead;
do
{
bytesRead = response.Read(buffer, 0, BUFFER_SIZE);
outputFileStream.Write(buffer, 0, bytesRead);
} while (bytesRead > 0);
}
outputFileStream.Flush();
}
}
}
catch (HttpRequestException hre)
{ //For debugging
this.Display.Text += hre.Message;
this.Display.Text += hre.Source;
}
catch (Exception ex)
{
//For debugging
this.Display.Text += ex.Message;
this.Display.Text += ex.Source;
}
So, to resume the download I would like to use some seek operation within the .Net client part.
But every time I try something like response.Seek(offset, response.Position); , an error occurs informing that the Stream does not support seek operations.
Yes, It does not, but how I can specify (in my server side) to use seekable Stream?
Does the method HttpExchange.setStreams can be useful?
Or, I do not need to modify the stream but to configure my HttpServer instance?
Thanks.
Well use Range, Accept-Range and Content-Range fields works. There is just a little bit of work to do in order to send the correct part of the file and to set the response's headers.
The server may inform client that it support the Range field by setting the Accept-Range field:
responseHeader.set("Accept-Ranges", "bytes");
And then set the Content-range field when partial file are sent :
responseHeader.set("Content-range", "bytes " + this.offSet + "-" + this.range + "/" + this.fileLength);
Finally the return code must be set to 206 (Partial Content).
For more information about Range, Accept-Range and Content-Range fields see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
NB : Opera 12.16 use the field "Range" to resume download but it seems that IE 10 and Firefox 22 do not use this field. May be some seekable streams as I was looking for originally. If anyone have an answer to this, I will be glad to read it =).
I am trying to work with Open Office in my Java app.
Based on SDK, with extra help from bootstrapconnector.jar I successfully started empty swritter and can write to the document.
Now, I would like to open document stored in ByteArray and after some modifications save changes doc to ByteArray.
Can somebody help me doing that, please?
Here is the SDK part starting sWritter.
public static com.sun.star.text.XTextDocument openWriter(
com.sun.star.uno.XComponentContext xContext) {
//define variables
com.sun.star.frame.XComponentLoader xCLoader;
com.sun.star.text.XTextDocument xDoc = null;
com.sun.star.lang.XComponent xComp = null;
try {
// get the remote office service manager
com.sun.star.lang.XMultiComponentFactory xMCF =
xContext.getServiceManager();
Object oDesktop = xMCF.createInstanceWithContext(
"com.sun.star.frame.Desktop", xContext);
xCLoader = (com.sun.star.frame.XComponentLoader) UnoRuntime.queryInterface(com.sun.star.frame.XComponentLoader.class,
oDesktop);
com.sun.star.beans.PropertyValue[] szEmptyArgs =
new com.sun.star.beans.PropertyValue[0];
String strDoc = "private:factory/swriter";
xComp = xCLoader.loadComponentFromURL(strDoc, "_blank", 0, szEmptyArgs);
xDoc = (com.sun.star.text.XTextDocument) UnoRuntime.queryInterface(com.sun.star.text.XTextDocument.class,
xComp);
} catch (Exception e) {
System.err.println(" Exception " + e);
e.printStackTrace(System.err);
}
return xDoc;
}
as you can see there is a method loadComponentFromURL.
I saw somewhere else, in the OOoBeanViewer, that it is possible to read and write doc to ByteArray, however I don't know how to achieve that without officebean.jar which I don't want to use in my project.
Thanks for your comments and hints.
I had a piece of code to read ofx file to retrieve several tags (such as acct number, balance etc.) I am using net.sf.ofx4j
Piece of code:
public void parse(String filename) throws OFXParseException, IOException, SQLException {
AggregateUnmarshaller<ResponseEnvelope> unmarshaller = new AggregateUnmarshaller<ResponseEnvelope>(
ResponseEnvelope.class);
FileInputStream file = null;
try {
file = new FileInputStream(filename);
ResponseEnvelope envelope = unmarshaller.unmarshal(file);
BankingResponseMessageSet messageSet = (BankingResponseMessageSet) envelope.getMessageSet(MessageSetType.banking);
List<BankStatementResponseTransaction> responses = messageSet.getStatementResponses();
for (BankStatementResponseTransaction response : responses) {
BankStatementResponse message = response.getMessage();
String currencyCode = message.getCurrencyCode();
String acct_number = message.getAccount().getAccountNumber();
double av = message.getAvailableBalance().getAmount();
double cur = message.getLedgerBalance().getAmount();
AccountType acct_type = message.getAccount().getAccountType();
}
} catch (OFXParseException e) {
System.out.println("Error: " + e.getMessage());
}
return null;
}
It was working fine until one day it started throwing the following exception:
net.sf.ofx4j.io.AggregateStackContentHandler onElement
INFO: Element INTU.BID is not supported on aggregate SONRS (class net.sf.ofx4j.domain.data.signon.SignonResponse) at index 70.
net.sf.ofx4j.io.AggregateStackContentHandler onElement
INFO: Element INTU.USERID is not supported on aggregate SONRS (class net.sf.ofx4j.domain.data.signon.SignonResponse) at index 70.
Exception in thread "main" java.lang.IllegalStateException: java.io.IOException: Unexpected EOF
Thanks
Hope ofx file format should be changed. because you are requesting (MessageSetType.*banking*). But in your ofx file may be have credit card details.
In early, transaction data is include in .ofx file inside the <BANKMSGSRSV1> tag.
But now transaction data is include in <CREDITCARDMSGSRSV> tag. you need to change the data receiving code.
Hope you can get some help from this. Thank you