解压缩的视频文件无法在Java中运行

时间:2013-02-12 15:33:17

标签: java compression

基本上我使用Java中的自定义压缩器类来压缩视频。我在这里汇总了我的完整代码片段。我的实际问题是,解压缩的字节数组生成的视频[A.mp4]没有运行。我实际上我通过互联网获得了这个压缩机类代码。作为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;
    }
}

2 个答案:

答案 0 :(得分:1)

两个提示:

1)用一个众所周知的API调用替换getBytesFromFile,使用Apache commons(IOUtils)或java 7现在也提供这样的方法。
2)通过编写Junit测试来测试compressdecompress: 创建一个随机的巨大字节数组,将其写出来,将其读回并与创建的数组进行比较。

答案 1 :(得分:1)

我通过压缩和解压缩简单的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%左右)。