mp4文件复制再写入后无法播放
mp4 file doesn't get played after being copied and written again
当我尝试使用 Mp4Parse 的一种方法将 mp4 从一个文件夹复制到另一个文件夹时,一切正常。当我尝试利用其中一种方法的输出来创建新对象,然后使用它们将文件写入另一个文件夹时,事情并没有完全解决。下面是我使用的代码:
我用这个class提取元数据并用相应的数据创建videoFile对象(评论是我用来确保它正常工作的剩余代码)
编辑 1:
经过一些测试后,我发现出于某种原因,即使 Mp4Parse.NoChunkMethod 中的 temp
不是空的或空的(我通过打印其所有内容来检查)方法 returns 的字节数组只有 0
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.util.ArrayList;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.mp4.MP4Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.SAXException;
public class Mp4Parse {
static int chunk_size = 512;
public ArrayList<videoFile> chunkingMethod(String arg) throws IOException,SAXException, TikaException {
String sourcefilePath = arg;
// String outputfilePath = "C:\Users\ilias-vasilis\Desktop\test1\video0.mp4";
//Next 2 lines exist only to give me the size of the file in bytes
Path path = Paths.get(sourcefilePath);
long fileSize = Files.size(path);
int chunk_num = (int)fileSize/chunk_size;
byte[] temp = new byte[(int)fileSize];
//data structure to store the chunks in
ArrayList<byte[]> chunks = new ArrayList<>(chunk_num);
//videoFile data structure
ArrayList<videoFile> video = new ArrayList<>(chunk_num);
//detecting the file type
BodyContentHandler handler = new BodyContentHandler();
Metadata metadata = new Metadata();
FileInputStream inputstream = new FileInputStream(sourcefilePath);
ParseContext pcontext = new ParseContext();
//Html parser
MP4Parser MP4Parser = new MP4Parser();
MP4Parser.parse(inputstream, handler, metadata,pcontext);
System.out.println("Contents of the document: :" + handler.toString());
System.out.println("Metadata of the document:");
String[] metadataNames = metadata.names();
for(String name : metadataNames) {
System.out.println(name + ": " + metadata.get(name));
}
inputstream.close();
FileInputStream myInputStream = new FileInputStream(new File(sourcefilePath));
// FileOutputStream outputStream = new FileOutputStream(new File(outputfilePath));
while(myInputStream.available() != 0) {
myInputStream.read(temp);
}
for(int j = 0; j < chunk_num; j++){
chunks.add(new byte[512]);
//Copy the elements of temp in chunks of "chunk_size"
System.arraycopy(temp, j * chunk_size, chunks.get(j), 0, chunk_size);
}
int i = 0;
//After splitting the mp4 in chunks make the videoFile objects
for(byte[] b:chunks) {
// outputStream.write(b);
video.add(new videoFile(b,null));
i++;
}
myInputStream.close();
return video;
// outputStream.close();
}
//##########################################################################################################################
//Simple transfer without splitting
public videoFile NoChunkMethod(String arg) throws IOException,SAXException, TikaException{
String sourcefilePath = arg;
// String outputfilePath = "C:\Users\ilias-vasilis\Desktop\Distributed-Systems-Project-main\Files\test\video1.mp4";
//Next 2 lines exist only to give me the size of the file in bytes
Path path = Paths.get(sourcefilePath);
long fileSize = Files.size(path);
byte[] temp = new byte[(int)fileSize];
//detecting the file type
BodyContentHandler handler = new BodyContentHandler();
Metadata metadata = new Metadata();
FileInputStream inputstream = new FileInputStream(sourcefilePath);
ParseContext pcontext = new ParseContext();
//Html parser
MP4Parser MP4Parser = new MP4Parser();
MP4Parser.parse(inputstream, handler, metadata,pcontext);
System.out.println("Contents of the document: :" + handler.toString());
System.out.println("Metadata of the document:");
String[] metadataNames = metadata.names();
for(String name : metadataNames) {
System.out.println(name + ": " + metadata.get(name));
}
inputstream.close();
FileInputStream myInputStream = new FileInputStream(new File(sourcefilePath));
// FileOutputStream outputStream = new FileOutputStream(new File(outputfilePath));
int bytesRead;
while(myInputStream.available() != 0) {
bytesRead = myInputStream.read(temp);
// outputStream.write(temp, 0, bytesRead);
}
myInputStream.close();
videoFile video = new videoFile(temp, null);
return video;
}
}
这几乎就是我想要存储视频的class。稍后我将开始为元数据赋值
import java.io.Serializable;
import java.util.*;
public class videoFile implements Serializable {
private static final long serialVersionUID = 1L;
String videoName; //Name of the video (video title)
String channelName; //Name of the channel it was posted on
String dateCreated; //The date it was uploaded or the date it is created (taken from metadata if possible)
String length; //Length of the video in seconds (Maybe declare it as int)
String framerate; //Self explanatory (maybe declare as int)
String frameWidth; //Width of the viewing window (maybe declare as int)
String frameHeight; //Same as above but with height
ArrayList<String> associatedHashtags; //Hashtags the publisher tagged the video with
byte[] videoFileChunk; //Byte array, possibly just used to store the entire vid or a single chunk to send over the Internet
int serialNumber = 0;
public videoFile(){
videoName = null;
channelName = null;
dateCreated = null;
length = null;
framerate = null;
frameWidth = null;
frameHeight = null;
associatedHashtags = null;
videoFileChunk = null;
serialNumber++;
}
public videoFile(byte[] chunk, String channelName){
videoName = null;
this.channelName = channelName;
dateCreated = null;
length = null;
framerate = null;
frameWidth = null;
frameHeight = null;
associatedHashtags = null;
videoFileChunk = new byte[chunk.length];
System.arraycopy(videoFileChunk, 0, chunk, 0, chunk.length);
serialNumber++;
}
public videoFile(String vname, String chname, String creationdate, String length,
String framerate, String frameWidth, String frameHeight,
ArrayList<String> hashtags, byte[] chunk)
{
videoName = vname;
channelName = chname;
dateCreated = creationdate;
this.length = length;
this.frameHeight = framerate;
this.frameWidth = frameWidth;
this.frameHeight = frameHeight;
associatedHashtags = new ArrayList<>(hashtags);
videoFileChunk = new byte[chunk.length];
System.arraycopy(videoFileChunk, 0, chunk, 0, chunk.length);
serialNumber++;
}
public videoFile(videoFile vidFile){
videoFileChunk = new byte[vidFile.videoFileChunk.length];
System.arraycopy(videoFileChunk, 0, vidFile.videoFileChunk,
0, vidFile.videoFileChunk.length);
this.channelName = vidFile.channelName;
videoName = null;
dateCreated = null;
length = null;
framerate = null;
frameWidth = null;
frameHeight = null;
associatedHashtags = null;
}
public videoFile(videoFile vidFile, String channelName){
this.channelName = channelName;
videoFileChunk = new byte[vidFile.videoFileChunk.length];
System.arraycopy(videoFileChunk, 0, vidFile.videoFileChunk,
0, vidFile.videoFileChunk.length);
videoName = null;
dateCreated = null;
length = null;
framerate = null;
frameWidth = null;
frameHeight = null;
associatedHashtags = null;
}
public byte[] getVideoFileChunk(){
return videoFileChunk;
}
}
这是我在 Mp4Parse 之外用于测试的代码
String path = "Files/ConsumerFiles/video1.mp4";
Mp4Parse mp4 = new Mp4Parse();
videoFile temp = new videoFile(mp4.NoChunkMethod(path));
videoFile video = new videoFile(temp, channelName);
FileOutputStream fop = new FileOutputStream("Files/test/video1.mp4");
fop.write(video.getVideoFileChunk());
fop.close();
此代码成功复制了正确大小的 mp4 文件,但视频无法播放,Windows 通知我它可能已损坏。
vidFile 的构造函数有问题。基本上我反向使用 Arrays.arraycopy 参数(我从空数组复制到完整数组)
当我尝试使用 Mp4Parse 的一种方法将 mp4 从一个文件夹复制到另一个文件夹时,一切正常。当我尝试利用其中一种方法的输出来创建新对象,然后使用它们将文件写入另一个文件夹时,事情并没有完全解决。下面是我使用的代码:
我用这个class提取元数据并用相应的数据创建videoFile对象(评论是我用来确保它正常工作的剩余代码)
编辑 1:
经过一些测试后,我发现出于某种原因,即使 Mp4Parse.NoChunkMethod 中的 temp
不是空的或空的(我通过打印其所有内容来检查)方法 returns 的字节数组只有 0
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.*;
import java.util.ArrayList;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.mp4.MP4Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.SAXException;
public class Mp4Parse {
static int chunk_size = 512;
public ArrayList<videoFile> chunkingMethod(String arg) throws IOException,SAXException, TikaException {
String sourcefilePath = arg;
// String outputfilePath = "C:\Users\ilias-vasilis\Desktop\test1\video0.mp4";
//Next 2 lines exist only to give me the size of the file in bytes
Path path = Paths.get(sourcefilePath);
long fileSize = Files.size(path);
int chunk_num = (int)fileSize/chunk_size;
byte[] temp = new byte[(int)fileSize];
//data structure to store the chunks in
ArrayList<byte[]> chunks = new ArrayList<>(chunk_num);
//videoFile data structure
ArrayList<videoFile> video = new ArrayList<>(chunk_num);
//detecting the file type
BodyContentHandler handler = new BodyContentHandler();
Metadata metadata = new Metadata();
FileInputStream inputstream = new FileInputStream(sourcefilePath);
ParseContext pcontext = new ParseContext();
//Html parser
MP4Parser MP4Parser = new MP4Parser();
MP4Parser.parse(inputstream, handler, metadata,pcontext);
System.out.println("Contents of the document: :" + handler.toString());
System.out.println("Metadata of the document:");
String[] metadataNames = metadata.names();
for(String name : metadataNames) {
System.out.println(name + ": " + metadata.get(name));
}
inputstream.close();
FileInputStream myInputStream = new FileInputStream(new File(sourcefilePath));
// FileOutputStream outputStream = new FileOutputStream(new File(outputfilePath));
while(myInputStream.available() != 0) {
myInputStream.read(temp);
}
for(int j = 0; j < chunk_num; j++){
chunks.add(new byte[512]);
//Copy the elements of temp in chunks of "chunk_size"
System.arraycopy(temp, j * chunk_size, chunks.get(j), 0, chunk_size);
}
int i = 0;
//After splitting the mp4 in chunks make the videoFile objects
for(byte[] b:chunks) {
// outputStream.write(b);
video.add(new videoFile(b,null));
i++;
}
myInputStream.close();
return video;
// outputStream.close();
}
//##########################################################################################################################
//Simple transfer without splitting
public videoFile NoChunkMethod(String arg) throws IOException,SAXException, TikaException{
String sourcefilePath = arg;
// String outputfilePath = "C:\Users\ilias-vasilis\Desktop\Distributed-Systems-Project-main\Files\test\video1.mp4";
//Next 2 lines exist only to give me the size of the file in bytes
Path path = Paths.get(sourcefilePath);
long fileSize = Files.size(path);
byte[] temp = new byte[(int)fileSize];
//detecting the file type
BodyContentHandler handler = new BodyContentHandler();
Metadata metadata = new Metadata();
FileInputStream inputstream = new FileInputStream(sourcefilePath);
ParseContext pcontext = new ParseContext();
//Html parser
MP4Parser MP4Parser = new MP4Parser();
MP4Parser.parse(inputstream, handler, metadata,pcontext);
System.out.println("Contents of the document: :" + handler.toString());
System.out.println("Metadata of the document:");
String[] metadataNames = metadata.names();
for(String name : metadataNames) {
System.out.println(name + ": " + metadata.get(name));
}
inputstream.close();
FileInputStream myInputStream = new FileInputStream(new File(sourcefilePath));
// FileOutputStream outputStream = new FileOutputStream(new File(outputfilePath));
int bytesRead;
while(myInputStream.available() != 0) {
bytesRead = myInputStream.read(temp);
// outputStream.write(temp, 0, bytesRead);
}
myInputStream.close();
videoFile video = new videoFile(temp, null);
return video;
}
}
这几乎就是我想要存储视频的class。稍后我将开始为元数据赋值
import java.io.Serializable;
import java.util.*;
public class videoFile implements Serializable {
private static final long serialVersionUID = 1L;
String videoName; //Name of the video (video title)
String channelName; //Name of the channel it was posted on
String dateCreated; //The date it was uploaded or the date it is created (taken from metadata if possible)
String length; //Length of the video in seconds (Maybe declare it as int)
String framerate; //Self explanatory (maybe declare as int)
String frameWidth; //Width of the viewing window (maybe declare as int)
String frameHeight; //Same as above but with height
ArrayList<String> associatedHashtags; //Hashtags the publisher tagged the video with
byte[] videoFileChunk; //Byte array, possibly just used to store the entire vid or a single chunk to send over the Internet
int serialNumber = 0;
public videoFile(){
videoName = null;
channelName = null;
dateCreated = null;
length = null;
framerate = null;
frameWidth = null;
frameHeight = null;
associatedHashtags = null;
videoFileChunk = null;
serialNumber++;
}
public videoFile(byte[] chunk, String channelName){
videoName = null;
this.channelName = channelName;
dateCreated = null;
length = null;
framerate = null;
frameWidth = null;
frameHeight = null;
associatedHashtags = null;
videoFileChunk = new byte[chunk.length];
System.arraycopy(videoFileChunk, 0, chunk, 0, chunk.length);
serialNumber++;
}
public videoFile(String vname, String chname, String creationdate, String length,
String framerate, String frameWidth, String frameHeight,
ArrayList<String> hashtags, byte[] chunk)
{
videoName = vname;
channelName = chname;
dateCreated = creationdate;
this.length = length;
this.frameHeight = framerate;
this.frameWidth = frameWidth;
this.frameHeight = frameHeight;
associatedHashtags = new ArrayList<>(hashtags);
videoFileChunk = new byte[chunk.length];
System.arraycopy(videoFileChunk, 0, chunk, 0, chunk.length);
serialNumber++;
}
public videoFile(videoFile vidFile){
videoFileChunk = new byte[vidFile.videoFileChunk.length];
System.arraycopy(videoFileChunk, 0, vidFile.videoFileChunk,
0, vidFile.videoFileChunk.length);
this.channelName = vidFile.channelName;
videoName = null;
dateCreated = null;
length = null;
framerate = null;
frameWidth = null;
frameHeight = null;
associatedHashtags = null;
}
public videoFile(videoFile vidFile, String channelName){
this.channelName = channelName;
videoFileChunk = new byte[vidFile.videoFileChunk.length];
System.arraycopy(videoFileChunk, 0, vidFile.videoFileChunk,
0, vidFile.videoFileChunk.length);
videoName = null;
dateCreated = null;
length = null;
framerate = null;
frameWidth = null;
frameHeight = null;
associatedHashtags = null;
}
public byte[] getVideoFileChunk(){
return videoFileChunk;
}
}
这是我在 Mp4Parse 之外用于测试的代码
String path = "Files/ConsumerFiles/video1.mp4";
Mp4Parse mp4 = new Mp4Parse();
videoFile temp = new videoFile(mp4.NoChunkMethod(path));
videoFile video = new videoFile(temp, channelName);
FileOutputStream fop = new FileOutputStream("Files/test/video1.mp4");
fop.write(video.getVideoFileChunk());
fop.close();
此代码成功复制了正确大小的 mp4 文件,但视频无法播放,Windows 通知我它可能已损坏。
vidFile 的构造函数有问题。基本上我反向使用 Arrays.arraycopy 参数(我从空数组复制到完整数组)