I want to add some string data to a video file but I don't want the video file to get corrupted. What I want to achieve is :-
1.) Add text to a video file.
2.) Extract the text from that video file.
What I tried is :-
public class VideoData{
public static void main(String[] args) {
//create file object
File file = new File("I:/java/MyFolder/SmallVideo.mp4");
try
{
//create FileInputStream object
FileInputStream fin = new FileInputStream(file);
byte fileContent[] = new byte[(int)file.length()];
fin.read(fileContent);
//create string from byte array
String strFileContent = new String(fileContent);
System.out.println("File content : ");
System.out.println(strFileContent);
File dest=new File("I://java//OtherFolder//SmallVideo.mp4");
BufferedWriter bw=new BufferedWriter(new FileWriter(dest));
bw.write(strFileContent + "\nThis is my Text");
bw.flush();
}
catch(FileNotFoundException e)
{
System.out.println("File not found" + e);
}
catch(IOException ioe)
{
System.out.println("Exception while reading the file " + ioe);
}
}
}
Please Help me to do the above mentioned tasks.
An MP4 file is a container that stores properly encoded video, audio, images and subtitles. It's a binary file with standard format specification which means you cannot simply add any extra data to it. Modifying the data could corrupt the file and the decoders (simply video players) might fail to render it.
Also in your code, you read the binary data from mp4 file and converted it to String. That shouldn't be the case. A video file data must be handled in binary mode, not as text.
I didn't understand your actual goal. If you are looking to store some text in MP4 file, you could consider storing it in the meta data section of the video file. See here for an example by using a third party library.
Steganography is a technique of embedding text in images and videos. I guess that's beyond your scope.
Related
I am trying to send Files in fragments using DatagramPackets in Java (part of an assignemt.) When I am trying to save the incoming File I get access denied error, but I believe that it is not a permissions issue.
Here is the brunt of it:
I let the user sending the file to choose it using FileChooser. And create a new Message object.
//....
File f = content.showFileChooser();
byte type = Byte.parseByte("4");
Message m;
try {
if (mode == 1){
m = new Message(f, content.getServerData().getFragmentSize(), (short) (sentMessages.size()+1), type);
serverThread.send(m);
}
//...
During Message creation the file gets split up into byte arrays, where the size of each array is predetermined by the user. The code is quite lengthy so I am not going to post the chopping process, but this is how I convert the File object into a big byte[] which then gets chopped up
Path p = Paths.get(file.getAbsolutePath());
this.rawData = Files.readAllBytes(p);
After the Message is created and chopped up into byte arrays I send them using DatagramPackets. The other side then uses those to create a new Message object. Once all fragments arrive rawData is extracted from the Message object again. The problem believe lies here:
Message m = receivedMessages.get(msgIndex-1);
byte[] fileData = m.getFile();
if (fileData != null){
System.out.println("All file fragments received.");
content.append("Received a file in" + m.getFragmentCount()+" fragments. Choose directory. " ,1);
//I BELIEVE THIS TO BE THE CRITICAL POINT
String filePath = content.chooseDirectory();
if (filePath == null)
return;
FileOutputStream fos;
try {
fos = new FileOutputStream(filePath);
fos.write(fileData);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Once all fragments arrive I let the user select a directory using FileChooser with DIRECTORY_ONLY choice mode. As I understand, FileOutputStream requires a full path for the new File. Do I have to send the file name and extension separately or can it be extracted from the received File data?
You are writing directory path to filePath, then try to open that directory with FileOutputStream. No wonder that doesn't work, you have to specify the filename too.
String filename = "myfile.txt"; //Or receive and set this some other way
File outFile = new File(filePath, filename);
fos = new FileOutputStream(outFile);
I don't see you sending/receiving the filename anywhere, though. You'll need to either make it constant or transfer it along with file contents.
I'm designing an Android application that would rely heavily on natural language processing for its purposes. I selected OpenNLP since it seems to offer what I need to offer, made a few classes to encapsulate tokenization, pos tagging, etc, and tested them out in a standard java setting with no issues.
My problem seems to be with the Android File system. OpenNLP calls for a training file to initialize the data model behind each class. However, the constructors for these classes seem to take in a very specific InputStream, as when I manage to successfully reference these files, I either get an error about the access permissions (I've added permissions for reading and writing from/to external storage), or an error stating that "The profile data stream has an invalid format!"
I'm at a loss, as using the standard input stream methods provided by the Android context class doesn't work as the provided input streams are of an invalid format, and attempting to manually access the files using my own input streams brings up permission problems. I've even tried loading the files at run time from the res folder into another file, and then re loading it using a normal FileInputStream, but this once again brings me to the invalid format problem.
Below is the method used to access the files, and an example method for initializing one of the models (they're all fairly uniform). If anybody has an idea what's going on, or if anybody has gotten OpenNLP to work in the Android environment, a little help would be greatly appreciated!
File Access Method:
protected FileInputStream importIfNotExists(){
FileInputStream input = null;
if(mContext != null){
File file = new File(getDirectory(), getFilePath());
if(file.exists()){ //Create input stream from file.
try {
Log.d("Analysis Tool", "Accessing file");
//Crashes here if it exists
input = new FileInputStream(file);
}
catch (FileNotFoundException e) {
Log.d("Speech Analysis Tool", "File not found: " + getFilePath());
input = null;
}
}
else{ //Import resource file, then get input stream
InputStream stream = null;
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
int sample = 0;
try {
Log.d("Analysis Tool", "Loading raw resource");
stream = mContext.getResources().openRawResource(mResId);
Log.d("Analysis Tool", "Creating file to be written to.");
file.createNewFile();
Log.d("Analysis Tool", "Reading bytes from resource.");
sample = stream.read();
while(sample != -1){
bytes.write(sample);
sample = stream.read();
}
stream.close();
Log.d("Analysis Tool", "Creating file: " + getFilePath());
FileOutputStream output = new FileOutputStream(file, false);
Log.d("Analysis Tool", "Writing bytes to " + getFilePath());
bytes.writeTo(output);
bytes.close();
output.close();
Log.d("Analysis Tool", "Retrieving input stream for new file");
input = new FileInputStream(file);
//the input passed from this is typically of an invalid format
}
catch (IOException e) {
Log.d("Speech Analysis Tool", "IOException with: " + getFilePath());
Log.e("Speech Analysis Tool", e.getLocalizedMessage());
input = null;
}
}
}
return input;
}
Model Initialization:
#Override
protected void initializeTool(FileInputStream input) throws InvalidFormatException, IOException{
if(input == null){
Log.e("Speech Tokenizer", "Input stream for tokenizer is null");
return;
}
TokenizerModel model = getModel(input);
mTokenizer = new TokenizerME(model);
}
getFilePath() simply returns the filename and its file type (like en_token.bin), and getDirectory() has varied with little to no success, but is intended to be the directory on external storage where I'd either access these files, or load them in at run time.
Add this line to your code:
System.setProperty("org.xml.sax.driver","org.xmlpull.v1.sax2.Driver");
Helped me, maybe it'll help you
I am working on a program that looks at an mp3 file and checks if it has it's ID3 data. If some data is missing it will query EchoNest (music database) for more data.
My problems is that when I update the ID3 tags Windows Explorer doesn't seem to recognize it (ie when the files are in the "Details" view the Artist, Title, Album columns are blank).
When I run my program a second time on the file my program finds the metadata just like it would find in a file that has all of it's data at first.
I am using the ID3 tag library found here:
http://javamusictag.sourceforge.net/
Is there something I am missing?
public void writeData(boolean pForce)
{
if (mIsUpdated || pForce)
{
try
{
File file = new File(mPath);
RandomAccessFile destFile = new RandomAccessFile(file, "rw");
ID3v1 tag = new ID3v1();
tag.setAlbum(mAlbum);
tag.setArtist(mArtist);
tag.setTitle(mTitle);
tag.write(destFile);
}
catch (FileNotFoundException ex)
{
System.out.println("No File Found At " + mPath);
}
catch (IOException ex)
{
System.out.println("Error when writting to file: " + mPath);
}
}
}
Just as a not I know that there are programs out there that do this same thing but I'm looking to add this as a function of my program. It's not so much about the functionality as it is about the learning how to make a program that does this.
Have you tried using ID3v2 tags, because when I was reading tags (with that library) from music files in windows, only v2 seemed to work. Hope it helps
EDIT:
If that doesn't work, I found this on another question using mp3agic: (the image stuff is to do with album artwork)
Mp3File song = new Mp3File(filename);
if (song.hasId3v2Tag()){
ID3v2 id3v2tag = song.getId3v2Tag();
byte[] imageData = id3v2tag.getAlbumImage();
//converting the bytes to an image
BufferedImage img = ImageIO.read(new ByteArrayInputStream(imageData));
}
I am sending a file in byte[] format from web service to android device.
If that file is an XML file i.e. byte[] array then how could i convert it to original XML file.
If that file is an image i.e. byte[] array then how could i convert it to original Image.
I am using android sdk 2.2 on samsung galaxy tab.
Your Webservice should send you some identifier about the file type. whether the byte array is for image or is for general file. then only you can know about which type of file it is. after knowing file type you can convert the byte array into your desired file type. Also you can write to file. If you want to print that xml in logcat you can use
String xmlData = new String(byte[] data); System.out.println(xmlData)
create a file (whether xml or image or anything) if you know the file format
String extension = ".xml"//or ".jpg" or anything
String filename = myfile+extension;
byte[] data = //the byte array which i got from server
File f = new File(givepathOfFile+filename );
try {
f.createNewFile();
// write the bytes in file
FileOutputStream fo = new FileOutputStream(f);
fo.write(data );
fo.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thanks
Deepak
A byte array containing XML already is an XML document. If you want to make it an XML file, then just write the bytes to a file.
The same applies for an image file.
Are you really just asking how to write a byte array as a file?
Here's how to write bytes to a file in Java.
byte[] bytes = ...
FileOutputStream fos = new FileOutputStream("someFile.xml");
try {
fos.write(bytes);
} finally {
fos.close();
}
Note that you need to close an opened stream in a finally block or else you risk leaking a file descriptors. If you leak too many file descriptors, later attempts to open files or sockets could start failing.
I am using Eclipse. I want to read number of XML files from a directory. Each XML file contains multiple body tags. I want to extract values of all the body tags. My problem is I have to save each body tag value (text) in a separate .txt file and add these text files in another given directory. Can you plz help how can I create dynamically .txt file and add them in a specified directory?
Thanks in advance.
First specify directory path and name
File dir=new File("Path to base dir");
if(!dir.exists){
dir.mkdir();}
//then generate File name
String fileName="generate required fileName";
File tagFile=new File(dir,fileName+".txt");
if(!tagFile.exists()){
tagFile.createNewFile();
}
add import for java.io.File;
File f;
f=new File("myfile.txt");
if(!f.exists()){
f.createNewFile();
replace "myfile.txt" to path to file you needed and file will be created when you say
e.g. "c:\\somedir\\yourfile.txt"
It's not clear why you have mentioned the XML part. But it seems that you are able to get the text from XML file and wanted to write to separate text file.
Please go through this basic tutorial for creating, reading and writing files in Java: http://download.oracle.com/javase/tutorial/essential/io/file.html
Path logfile = ...;
//Convert the string to a byte array.
String s = ...;
byte data[] = s.getBytes();
OutputStream out = null;
try {
out = new BufferedOutputStream(logfile.newOutputStream(CREATE, APPEND));
...
out.write(data, 0, data.length);
} catch (IOException x) {
System.err.println(x);
} finally {
if (out != null) {
out.flush();
out.close();
}
}
Do something like this.
try {
//Specify directory
String directory = //TODO....
//Specify filename
String filename= //TODO....
// Create file
FileWriter fstream = new FileWriter(directory+filename+".txt");
BufferedWriter out = new BufferedWriter(fstream);
//insert your xml content here
out.write("your xml content");
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
} finally {
//Close the output stream
out.close();
}