Cannot retrieve native file ffmpeg-amd64.exe - java

I am trying to convert video to audio . That is why , I am using the following code :
File source = new File("E:\\Shunno - Khachar Bhitor Ochin Pakhi.mp4");
File target = new File("E:\\output.mp3");
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(new Integer(128000));
audio.setChannels(new Integer(2));
audio.setSamplingRate(new Integer(44100));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("mp3");
attrs.setAudioAttributes(audio);
Encoder encoder = new Encoder();
try
{
encoder.encode(source, target, attrs);
}
catch (IllegalArgumentException | EncoderException e)
{
}
But I am getting the following error :
Sep 26, 2016 11:28:29 AM it.sauronsoftware.jave.DefaultFFMPEGLocator copyFile
SEVERE: Could not get native library for ffmpeg-amd64.exe
Exception in thread "main" java.lang.RuntimeException: Cannot retrieve native file ffmpeg-amd64.exe
at it.sauronsoftware.jave.DefaultFFMPEGLocator.copyFile(DefaultFFMPEGLocator.java:139)
at it.sauronsoftware.jave.DefaultFFMPEGLocator.<init>(DefaultFFMPEGLocator.java:80)
at it.sauronsoftware.jave.Encoder.<init>(Encoder.java:105)
at Convert.main(Convert.java:29)
How can I solve this error ? Please help me .

The error is very clear: ffmpeg cannot been found.
Since you hard coded some windows path here is the windows binary of ffmpeg. I suggest to download the x64 static version. Since that is just one file you need to care about.
If you need it for another platform check the download site.
Within the zip file in the subdirectory bin where the binary ffmpeg.exe is located. Now you need to renamed it to ffmpeg-amd64.exe since the library expects that name. Now you need to copy the file to a directory of your path variable e.g. C:\windows\system32. I suggest not to use that directory, but this is the simplest way. Better put it somewhere else and modify your path variable. There are dozens of explanations so just google them if you want how do achieve that.

Related

Unable to read resources from .jar [duplicate]

This question already has answers here:
Java Jar file: use resource errors: URI is not hierarchical
(6 answers)
Closed 6 years ago.
I have files in resource folder. For example if I need to get file from resource folder, I do like that:
File myFile= new File(MyClass.class.getResource(/myFile.jpg).toURI());
System.out.println(MyClass.class.getResource(/myFile.jpg).getPath());
I've tested and everything works!
The path is
/D:/java/projects/.../classes/X/Y/Z/myFile.jpg
But, If I create jar file, using , Maven:
mvn package
...and then start my app:
java -jar MyJar.jar
I have that following error:
Exception in thread "Thread-4" java.lang.RuntimeException: ხელმოწერის განხორციელება შეუძლებელია
Caused by: java.lang.IllegalArgumentException: URI is not hierarchical
at java.io.File.<init>(File.java:363)
...and path of file is:
file:/D:/java/projects/.../target/MyJar.jar!/X/Y/Z/myFile.jpg
This exception happens when I try to get file from resource folder. At this line. Why? Why have that problem in JAR file? What do you think?
Is there another way, to get the resource folder path?
You should be using
getResourceAsStream(...);
when the resource is bundled as a jar/war or any other single file package for that matter.
See the thing is, a jar is a single file (kind of like a zip file) holding lots of files together. From Os's pov, its a single file and if you want to access a part of the file(your image file) you must use it as a stream.
Documentation
Here is a solution for Eclipse RCP / Plugin developers:
Bundle bundle = Platform.getBundle("resource_from_some_plugin");
URL fileURL = bundle.getEntry("files/test.txt");
File file = null;
try {
URL resolvedFileURL = FileLocator.toFileURL(fileURL);
// We need to use the 3-arg constructor of URI in order to properly escape file system chars
URI resolvedURI = new URI(resolvedFileURL.getProtocol(), resolvedFileURL.getPath(), null);
File file = new File(resolvedURI);
} catch (URISyntaxException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
It's very important to use FileLocator.toFileURL(fileURL) rather than resolve(fileURL)
, cause when the plugin is packed into a jar this will cause Eclipse to create an unpacked version in a temporary location so that the object can be accessed using File. For instance, I guess Lars Vogel has an error in his article - http://blog.vogella.com/2010/07/06/reading-resources-from-plugin/
I face same issue when I was working on a project in my company. First Of All, The URI is not hierarichal Issue is because probably you are using "/" as file separator.
You must remember that "/" is for Windows and from OS to OS it changes, It may be different in Linux. Hence Use File.seperator .
So using
this.getClass().getClassLoader().getResource("res"+File.separator+"secondFolder")
may remove the URI not hierarichal. But Now you may face a Null Pointer Exception. I tried many different ways and then used JarEntries Class to solve it.
File jarFile = new File(this.getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
String actualFile = jarFile.getParentFile().getAbsolutePath()+File.separator+"Name_Of_Jar_File.jar";
System.out.println("jarFile is : "+jarFile.getAbsolutePath());
System.out.println("actulaFilePath is : "+actualFile);
final JarFile jar = new JarFile(actualFile);
final Enumeration<JarEntry> entries = jar.entries(); //gives ALL entries in jar
System.out.println("Reading entries in jar file ");
while(entries.hasMoreElements()) {
JarEntry jarEntry = entries.nextElement();
final String name = jarEntry.getName();
if (name.startsWith("Might Specify a folder name you are searching for")) { //filter according to the path
System.out.println("file name is "+name);
System.out.println("is directory : "+jarEntry.isDirectory());
File scriptsFile = new File(name);
System.out.println("file names are : "+scriptsFile.getAbsolutePath());
}
}
jar.close();
You have to specify the jar name here explicitly. So Use this code, this will give you directory and sub directory inside the folder in jar.

Converting an MP3 to a video format using JAVE

I am trying to convert a audio (mp3) file to a video file (ideally flv or anything that youtube will accept). Looking around on here I thought that JAVE might be able to do the job and have been playing around with it but most of the support is about extracting the audio from a video rather than the other way around. I was guessing that I might need a blank image or something to form the pictures part of the video but can't seem to work it out. Thanks for any and all help!
My current code looks like :
File source = new File("voicetomstest.mp3");
File target = new File("target.flv");
AudioAttributes audio = new AudioAttributes();
audio.setCodec("libmp3lame");
audio.setBitRate(new Integer(64000));
audio.setChannels(new Integer(1));
audio.setSamplingRate(new Integer(22050));
VideoAttributes video = new VideoAttributes();
video.setCodec("flv");
video.setBitRate(new Integer(160000));
video.setFrameRate(new Integer(15));
video.setSize(new VideoSize(400, 300));
EncodingAttributes attrs = new EncodingAttributes();
attrs.setFormat("flv");
attrs.setAudioAttributes(audio);
attrs.setVideoAttributes(video);
Encoder encoder = new Encoder();
encoder.encode(source, target, attrs);
And currently has the following error
Apr 01, 2018 3:13:34 PM testvoice2video.TestVoice2Video main
SEVERE: null
it.sauronsoftware.jave.InputFormatException
at it.sauronsoftware.jave.Encoder.parseMultimediaInfo(Encoder.java:659)
at it.sauronsoftware.jave.Encoder.encode(Encoder.java:840)
at it.sauronsoftware.jave.Encoder.encode(Encoder.java:713)
at testvoice2video.TestVoice2Video.main(TestVoice2Video.java:74)
where line 74 is "encoder.encode(source, target, attrs);"
I don't work with this code, but it appears to me from looking at the Encoder.parseMultiMediaInfo() source code that the InputFormatException thrown at line 659 is a result of not being able to create a MultimediaInfo file from your target. It's looking for this regexp at the beginning of the target:
^\\s*Input #0, (\\w+).+$\\s*"
The target file is opened as an ffmpeg executable, where various arguments are then added as per your attributes. I don't know what ffmpeg argument results in a "Input #0" type header but I have to assume it's the
...
ffmpeg.addArgument("-i");
ffmpeg.addArgument(source.getAbsolutePath());
...
Are you sure your source file is being found?

Java access files in jar causes java.nio.file.FileSystemNotFoundException

While trying to copy some files in my jar file to a temp directory with my java app, the following exception is thrown:
java.nio.file.FileSystemNotFoundException
at com.sun.nio.zipfs.ZipFileSystemProvider.getFileSystem(ZipFileSystemProvider.java:171)
at com.sun.nio.zipfs.ZipFileSystemProvider.getPath(ZipFileSystemProvider.java:157)
at java.nio.file.Paths.get(Unknown Source)
at com.sora.util.walltoggle.pro.WebViewPresentation.setupTempFiles(WebViewPresentation.java:83)
....
and this is a small part of my setupTempFiles(with line numbers):
81. URI uri = getClass().getResource("/webViewPresentation").toURI();
//prints: URI->jar:file:/C:/Users/Tom/Dropbox/WallTogglePro.jar!/webViewPresentation
82. System.out.println("URI->" + uri );
83. Path source = Paths.get(uri);
the webViewPresentation directory resides in the root directory of my jar:
This problem only exits when I package my app as a jar, debugging in Eclipse has no problems. I suspect that this has something to do with this bug but I'm not sure how to correct this problem.
Any helps appreciated
If matters:
I'm on Java 8 build 1.8.0-b132
Windows 7 Ult. x64
A FileSystemNotFoundException means the file system cannot be created automatically; and you have not created it here.
Given your URI, what you should do is split against the !, open the filesystem using the part before it and then get the path from the part after the !:
final Map<String, String> env = new HashMap<>();
final String[] array = uri.toString().split("!");
final FileSystem fs = FileSystems.newFileSystem(URI.create(array[0]), env);
final Path path = fs.getPath(array[1]);
Note that you should .close() your FileSystem once you're done with it.
Accepted answer isn't the best since it doesn't work when you start application in IDE or resource is static and stored in classes!
Better solution was proposed at java.nio.file.FileSystemNotFoundException when getting file from resources folder
InputStream in = getClass().getResourceAsStream("/webViewPresentation");
byte[] data = IOUtils.toByteArray(in);
IOUtils is from Apache commons-io.
But if you are already using Spring and want a text file you can change the second line to
StreamUtils.copyToString(in, Charset.defaultCharset());
StreamUtils.copyToByteArray also exists.
This is maybe a hack, but the following worked for me:
URI uri = getClass().getResource("myresourcefile.txt").toURI();
if("jar".equals(uri.getScheme())){
for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
if (provider.getScheme().equalsIgnoreCase("jar")) {
try {
provider.getFileSystem(uri);
} catch (FileSystemNotFoundException e) {
// in this case we need to initialize it first:
provider.newFileSystem(uri, Collections.emptyMap());
}
}
}
}
Path source = Paths.get(uri);
This uses the fact that ZipFileSystemProvider internally stores a List of FileSystems that were opened by URI.
If you're using spring framework library, then there is an easy solution for it.
As per requirement we want to read webViewPresentation;
I could solve the same problem with below code:
URI uri = getClass().getResource("/webViewPresentation").toURI();
FileSystems.getDefault().getPath(new UrlResource(uri).toString());

Understanding Simple XML Parser - New File Output - Java

I am trying to learn how to use the Simple XML Framework as detailed in this thread : Best practices for parsing XML.
I am using the following code :
public class SimpleXMLParserActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
Serializer serializer = new Persister();
Example example = new Example("Example message", 123);
File result = new File("example.xml");
try {
Log.d("Start", "Starting Serializer");
serializer.write(example, result);
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("Self", "Error");
e.printStackTrace();
}
}
}
I am having a problem understanding the line
File result = new File("example.xml");
1) Does this line create a new file in my app called example.xml ? If so where is this file located.
2) Or does this line look for an existing file called example.xml and then add to it ? If so where should the example.xml file be placed in my app bundle so that it can be found. I do notice at the moment I am getting an error message :
java.io.FileNotFoundException: /example.xml (Read-only file system)
Thank you.
File result = new File("example.xml")
This line will just store the filename "example.xml" in a new File object. There is no check if that file actually exists and it does not try to create it either.
A file without specifying an absolute path (starting with / like new File("/sdcard/example.xml")) is considered to be in the current working directory which I guess is / for Android apps (-> /example.xml (Read-only file system))
I guess serializer.write(example, result); tries to create the actual file for your but fails since you can't write to '/'.
You have to specify a path for that file. There are several places you can store files, e.g.
Context#getFilesDir() will give you a place in your app's home directory (/data/data/your.package/files/) where only you can read / write - without extra permission.
Environment#getExternalStorageDirectory() will give you the general primary storage thing (might be /sdcard/ - but that's very different for devices). To write here you'll need the WRITE_EXTERNAL_STORAGE permission.
there are more places available in Environment that are more specialized. E.g. for media files, downloads, caching, etc.
there is also Context#getExternalFilesDir() for app private (big) files you want to store on the external storage (something like /sdcard/Android/data/your.package/)
to fix your code you could do
File result = new File(Environment.getExternalStorageDirectory(), "example.xml");
Edit: either use the provided mechanisms to get an existing directory (preferred but you are limited to the folders you are supposed to use):
// via File - /data/data/your.package/app_assets/example.xml
File outputFile = new File(getDir("assets", Context.MODE_PRIVATE), "example.xml");
serializer.write(outputFile, result);
// via FileOutputStream - /data/data/your.package/files/example.xml
FileOutputStream outputStream = openFileOutput("example.xml", Context.MODE_PRIVATE);
serializer.write(outputStream, result);
or you may need to create the directories yourself (hackish way to get your app dir but it should work):
File outputFile = new File(new File(getFilesDir().getParentFile(), "assets"), "example.xml");
outputFile.mkdirs();
serializer.write(outputFile, result);
Try to avoid specifying full paths like "/data/data/com.simpletest.test/assets/example.xml" since they might be different on other devices / Android versions. Even the / is not guaranteed to be /. It's safer to use File.separatorChar instead if you have to.
2 solutions to do it cleanly :
use openFileOutput to write a private file in the application private directory (which could be located in the internal memory or the external storage if the app was moved there). See here for a snippet
or use the File constructor to create the File anywhere your app has write access. This is if you want to store the file on the SDCard for example. Instantiating a file doesn't create it on the file system, unless you start writiung to it (with FileOutputStream for example)
I'd recommend approach 1, it's better for users because these files get erased when your app is uninstalled. If the file is large, then using the External Storage is probably better.
What I read on the Android pages, I see it creates a file with that name:
File constructor
I think it writes it to the /data/data/packagname directory
edit: the 'packagename' was not shown in the tekst above. I put it between brackets. :s
Try saving to /sdcard/example.xml.

File.getCanonicalPath() failure examples

Does anyone have an experience or know when the method File.getCanonicalPath() will throw an IOException
I have tried to look up from the Internet and the best answer is in File API which says
"IOException - If an I/O error occurs, which is possible because the construction of the canonical pathname may require filesystem queries"
However, it is not clear to me because I still cannot think of a case which this might fail. Can anyone give me concrete examples which can happen on Linux, Windows and other OS (optional)?
I reason I want to know is because I want to handle this exception accordingly. Thus, it will be best if I know all the possible failures that can happen.
Here is a Windows example:
Try calling getCanonicalFile on a file in your CD-drive, but without a CD loaded. For example:
new File("D:\\dummy.txt").getCanonicalFile();
you will get:
Exception in thread "main" java.io.IOException: The device is not ready
at java.io.WinNTFileSystem.canonicalize0(Native Method)
at java.io.Win32FileSystem.canonicalize(Win32FileSystem.java:396)
at java.io.File.getCanonicalPath(File.java:559)
at java.io.File.getCanonicalFile(File.java:583)
The IO Exception also occurs if we try creating a File object with Windows device file keywords (see device files) used as file name.
As if you try renaming the file to those keywords, Windows will not let you to make it (no CON, PRN, COM1 etc. file names allowed), Java also won't be able to convert that file name to the correct path.
So, any of next next code will trow the IO Exception:
File file = new File("COM1").getContextPath();
File file = new File("COM1.txt").getContextPath();
File file = new File("C:/somefolder/COM1.txt").getContextPath();
However, next code should work:
File file = new File("COM1_.txt").getContextPath(); //underscore wins :)
Here is generic example for all OS:
new File("\u0000").getCanonicalFile();
Before canonicalizing of the file, its validity is checked with java.io.File#isInvalid:
final boolean isInvalid() {
if (status == null) {
status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
: PathStatus.INVALID;
}
return status == PathStatus.INVALID;
}
And if the file is invalid - you'll get an IO exception:
public String getCanonicalPath() throws IOException {
if (isInvalid()) {
throw new IOException("Invalid file path");
}
return fs.canonicalize(fs.resolve(this));
}
Profit!
Seen here in the Sun Bug Database.
For JRE 1.4.2_06, File.getCanonicalPath() wasn't working on Windows for a removable drive when there is no media present in the drive.
It was corrected in Java 1.5, but you can see there can be OS-based problems with this method.
I don't know of any problem in the current time, but it can happen, that's exactly what the Javadoc says. Usually it's quickly fixed in the newest Java version.
One more scenario, When you try to use Operating System restricted/invalid characters as your file name.
For Windows \ / : * ? " < > | these are the invalid characters. Try to rename a file with : you will get a balloon/tip message about the invalid characters.
Try the Following Java Code.
File file = new File("c:/outputlog-2013-09-20-22:15");
//A common scenario when you try to append java.util.Date to create a file like
//File newFile = new File(filename + "_" + new Date());
System.out.println(file.getAbsolutePath());
System.out.println(file.getCanonicalPath());
If the File name contains
* ? you will get java.io.IOException: Invalid argument
| : you will get java.io.IOException: The filename, directory name, or volume label syntax is incorrect
when you use the getCanonicalPath() method. If we use any of " < >
char in the file name, then getCanonicalPath() method is not failing but when you try to create the file you will be getting the Invalid argument Exception.
Refer jdk7 api
The precise definition of canonical form is system-dependent. Here I have used windows 7.

Categories

Resources