解压缩的视频文件在Java中不起作用
问题描述:
基本上我使用Java中定制的压缩器类压缩视频。我已经在这里汇集了我的完整代码片段。我真正的问题是,从解压缩的字节数组生成的视频[A.mp4]没有运行。实际上,我通过互联网获得了压缩机班的代码。由于我是Java平台的新手,我正在努力解决这个问题。你能请任何人帮我解决这个问题吗?解压缩的视频文件在Java中不起作用
public class CompressionTest
{
public static void main(String[] args)
{
Compressor compressor = new Compressor();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis=null;
File file=null;
try
{
URL uri=CompressionTest.class.getResource("/Files/Video.mp4");
file=new File(uri.getPath());
fis = new FileInputStream(file);
}
catch (FileNotFoundException fnfe)
{
System.out.println("Unable to open input file");
}
try
{
byte[] videoBytes = getBytesFromFile(file);
System.out.println("CompressionVideoToCompress is: '" +videoBytes + "'");
byte[] bytesCompressed = compressor.compress(videoBytes);
System.out.println("bytesCompressed is: '" +bytesCompressed+ "'");
byte[] bytesDecompressed=compressor.decompress(bytesCompressed);
System.out.println("bytesDecompressed is: '" +bytesDecompressed+ "'");
FileOutputStream out = new FileOutputStream("A.mp4");
out.write(bytesDecompressed,0,bytesDecompressed.length-1);
out.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
System.out.println("bytesCompressed is: '");
}
}
public static byte[] getBytesFromFile(File file) throws IOException
{
InputStream is = new FileInputStream(file);
// Get the size of the file
long length = file.length();
// You cannot create an array using a long type.
// It needs to be an int type.
// Before converting to an int type, check
// to ensure that file is not larger than Integer.MAX_VALUE.
if (length > Integer.MAX_VALUE) {
// File is too large
}
// Create the byte array to hold the data
byte[] bytes = new byte[1064];
// Read in the bytes
int offset = 0;
int numRead = 0;
while (offset < bytes.length
&& (numRead=is.read(bytes, offset, bytes.length-offset)) >= 0)
{
offset += numRead;
}
// Ensure all the bytes have been read in
if (offset < bytes.length) {
throw new IOException("Could not completely read file "+file.getName());
}
// Close the input stream and return bytes
is.close();
return bytes;
}
}
class Compressor
{
public Compressor()
{}
public byte[] compress(byte[] bytesToCompress)
{
Deflater deflater = new Deflater();
deflater.setInput(bytesToCompress);
deflater.finish();
byte[] bytesCompressed = new byte[Short.MAX_VALUE];
int numberOfBytesAfterCompression = deflater.deflate(bytesCompressed);
byte[] returnValues = new byte[numberOfBytesAfterCompression];
System.arraycopy
(
bytesCompressed,
0,
returnValues,
0,
numberOfBytesAfterCompression
);
return returnValues;
}
public byte[] decompress(byte[] bytesToDecompress)
{
Inflater inflater = new Inflater();
int numberOfBytesToDecompress = bytesToDecompress.length;
inflater.setInput
(
bytesToDecompress,
0,
numberOfBytesToDecompress
);
int compressionFactorMaxLikely = 3;
int bufferSizeInBytes =
numberOfBytesToDecompress
* compressionFactorMaxLikely;
byte[] bytesDecompressed = new byte[bufferSizeInBytes];
byte[] returnValues = null;
try
{
int numberOfBytesAfterDecompression = inflater.inflate(bytesDecompressed);
returnValues = new byte[numberOfBytesAfterDecompression];
System.arraycopy
(
bytesDecompressed,
0,
returnValues,
0,
numberOfBytesAfterDecompression
);
}
catch (DataFormatException dfe)
{
dfe.printStackTrace();
}
inflater.end();
return returnValues;
}
}
答
我已经通过压缩和解压简单的TXT文件测试了你的代码。代码是中断,因为压缩文件在未压缩时与原始压缩文件不同。
认为该代码被破坏至少在getBytesFromFile
函数。它的逻辑是棘手和麻烦的,因为它只允许长度为1064的文件,并且检查(在读取更长的文件时抛出IOException
)完全不起作用。该文件只能部分读取,不会抛出异常。
您可以通过这种方式完成您想要实现的功能(文件压缩/解压缩)。我已经测试过它,它的工作原理,你只需要this library。
import java.io.*;
import java.util.zip.*;
import org.apache.commons.io.IOUtils; // <-- get this from http://commons.apache.org/io/index.html
public class CompressionTest2 {
public static void main(String[] args) throws IOException {
File input = new File("input.txt");
File output = new File("output.bin");
Compression.compress(input, output);
File input2 = new File("input2.txt");
Compression.decompress(output, input2);
// At this point, input.txt and input2.txt should be equal
}
}
class Compression {
public static void compress(File input, File output) throws IOException {
FileInputStream fis = new FileInputStream(input);
FileOutputStream fos = new FileOutputStream(output);
GZIPOutputStream gzipStream = new GZIPOutputStream(fos);
IOUtils.copy(fis, gzipStream);
gzipStream.close();
fis.close();
fos.close();
}
public static void decompress(File input, File output) throws IOException {
FileInputStream fis = new FileInputStream(input);
FileOutputStream fos = new FileOutputStream(output);
GZIPInputStream gzipStream = new GZIPInputStream(fis);
IOUtils.copy(gzipStream, fos);
gzipStream.close();
fis.close();
fos.close();
}
}
此代码不是来自“可信和/或官方消息”,但至少它的工作原理。 :)
此外,为了获得更多的答案,调整标题说明你真正的问题:你的压缩文件不解压正确的方式。这里没有'视频'的东西。此外,压缩.mp4
文件是没有成就的(压缩率可能会在99.99%左右)。
答
两个尖端:
1)用众所周知的API调用替换getBytesFromFile
,无论是使用Apache公地(IOUtils)或Java 7现在提供了这样的方法,也。
2)通过编写一个Junit测试测试compress
和decompress
: 创建一个随机的巨大字节数组,写出来,读回来并与创建的数据进行比较。
gd1: - 压缩和解压缩对我来说可以正常工作。但是,如果我尝试打开视频的压缩字节,它不会显示任何内容。但它运行.. – 2013-02-19 06:32:32
与您的代码或与我的?在这两种情况下,一旦你执行这种压缩,除非你解压它,否则这个文件是不可读的。这不是视频压缩,它是一种通用的二进制无损压缩,如WinZip。压缩文件 – gd1 2013-02-19 09:10:08
gd1: - 仅限您的代码。我们是否可以通过任何方法使压缩文件可读? – 2013-02-19 09:20:34