2013-02-12 40 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