java - 解压缩的视频文件在 Java 中不起作用

标签 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;
    }
}

最佳答案

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

关于java - 解压缩的视频文件在 Java 中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14836015/

相关文章:

MySQL innodb COMPRESSED中KEY_BLOCK_SIZE取值注意事项

algorithm - 压缩打乱的整数序列 [0, N)

java - 管理桌面应用程序中的状态?

Java发送post登录请求

java - 为什么我不能使用三元组?运算符在两个函数调用之间进行选择?

php - 压缩存储在mysql中的数据

javascript - 使网站加载更快

java - 如何从另一个字符串中获取一个字符串值

java - 如何一起对 Kafka Streams 和 Producer API 进行单元测试

c# - 如何在 zip 存档中找到某些文件的压缩位以进行进一步处理?