1

基本的に、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;
    }
}
4

2 に答える 2

1

2つのヒント:

1)getBytesFromFileApache Commons(IOUtils)を使用するか、Java 7でもそのようなメソッドが提供されるようになり、よく知られたAPI呼び出しに置き換えます。
2)テストcompressdecompressJUnitテストの記述による:ランダムな巨大バイト配列を作成し、それを書き出し、読み戻し、作成されたものと比較します。

于 2013-02-18T12:07:34.053 に答える
1

単純なTXTファイルを圧縮および解凍してコードをテストしました。圧縮されていないファイルは元のファイルとは異なるため、コードが壊れています。

少なくともgetBytesFromFile関数内でコードが壊れていることは当然のことと考えてください。そのロジックは、長さが1064までのファイルしか許可せず、チェック(IOExceptionより長いファイルが読み取られたときにスローされる)がまったく機能しないため、トリッキーで面倒です。ファイルは部分的にのみ読み取られ、例外はスローされません。

あなたが達成しようとしていること(ファイルの圧縮/解凍)はこの方法で行うことができます。私はそれをテストしました、そしてそれは働きます、あなたはただこのライブラリを必要とします。

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%になる可能性があります)。

于 2013-02-18T12:14:02.557 に答える