2013-02-12 83 views
1

基本上我使用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; 
    } 
} 

回答

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%左右)。

+0

gd1: - 压缩和解压缩对我来说可以正常工作。但是,如果我尝试打开视频的压缩字节,它不会显示任何内容。但它运行.. – 2013-02-19 06:32:32

+0

与您的代码或与我的?在这两种情况下,一旦你执行这种压缩,除非你解压它,否则这个文件是不可读的。这不是视频压缩,它是一种通用的二进制无损压缩,如WinZip。压缩文件 – gd1 2013-02-19 09:10:08

+0

gd1: - 仅限您的代码。我们是否可以通过任何方法使压缩文件可读? – 2013-02-19 09:20:34

1

两个尖端:

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

+0

并忘记压缩mp4它已经是最好的可能的压制。 – AlexWien 2013-02-18 12:31:15

+0

为什么取消upvote?我告诉evrything其他海报编码了什么:(使用IOUtils,并测试你的压缩/解压缩) – AlexWien 2013-02-19 12:20:11