【问题标题】:How to compress video and upload to server? [duplicate]如何压缩视频并上传到服务器? [复制]
【发布时间】:2014-07-30 16:25:51
【问题描述】:

我是 Android 开发新手,无法将视频压缩到 Android 应用程序中。

所以,请帮我以编程方式压缩视频并上传到服务器。

我使用过 FFmpeg,但不知道如何正确使用它。请指导我这样做。

【问题讨论】:

    标签: android


    【解决方案1】:

    客户端(ANDROID)代码

        package pack.coderzheaven;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.util.HashMap;
    import android.app.Activity;
    import android.content.Intent;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Environment;
    import android.provider.MediaStore;
    import android.util.Log;
    
    public class UploadAudioDemo extends Activity {
    
        private static final int SELECT_AUDIO = 2;
        String selectedPath = "";
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            openGalleryAudio();
        }
    
        public void openGalleryAudio(){
    
        Intent intent = new Intent();
            intent.setType("audio/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            startActivityForResult(Intent.createChooser(intent,"Select Audio "), SELECT_AUDIO);
       }
    
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
    
            if (resultCode == RESULT_OK) {
    
                if (requestCode == SELECT_AUDIO)
                {
                    System.out.println("SELECT_AUDIO");
                    Uri selectedImageUri = data.getData();
                    selectedPath = getPath(selectedImageUri);
                    System.out.println("SELECT_AUDIO Path : " + selectedPath);
                    doFileUpload();
                }
    
            }
        }
    
        public String getPath(Uri uri) {
            String[] projection = { MediaStore.Images.Media.DATA };
            Cursor cursor = managedQuery(uri, projection, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        }
    
        private void doFileUpload(){
            HttpURLConnection conn = null;
            DataOutputStream dos = null;
            DataInputStream inStream = null;
            String lineEnd = "rn";
            String twoHyphens = "--";
            String boundary =  "*****";
            int bytesRead, bytesAvailable, bufferSize;
            byte[] buffer;
            int maxBufferSize = 1*1024*1024;
            String responseFromServer = "";
            String urlString = "http://your_website.com/upload_audio_test/upload_audio.php";
            try
            {
             //------------------ CLIENT REQUEST
            FileInputStream fileInputStream = new FileInputStream(new File(selectedPath) );
             // open a URL connection to the Servlet
             URL url = new URL(urlString);
             // Open a HTTP connection to the URL
             conn = (HttpURLConnection) url.openConnection();
             // Allow Inputs
             conn.setDoInput(true);
             // Allow Outputs
             conn.setDoOutput(true);
             // Don't use a cached copy.
             conn.setUseCaches(false);
             // Use a post method.
             conn.setRequestMethod("POST");
             conn.setRequestProperty("Connection", "Keep-Alive");
             conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
             dos = new DataOutputStream( conn.getOutputStream() );
             dos.writeBytes(twoHyphens + boundary + lineEnd);
             dos.writeBytes("Content-Disposition: form-data; name="uploadedfile";filename="" + selectedPath + """ + lineEnd);
             dos.writeBytes(lineEnd);
             // create a buffer of maximum size
             bytesAvailable = fileInputStream.available();
             bufferSize = Math.min(bytesAvailable, maxBufferSize);
             buffer = new byte[bufferSize];
             // read file and write it into form...
             bytesRead = fileInputStream.read(buffer, 0, bufferSize);
             while (bytesRead > 0)
             {
              dos.write(buffer, 0, bufferSize);
              bytesAvailable = fileInputStream.available();
              bufferSize = Math.min(bytesAvailable, maxBufferSize);
              bytesRead = fileInputStream.read(buffer, 0, bufferSize);
             }
             // send multipart form data necesssary after file data...
             dos.writeBytes(lineEnd);
             dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
             // close streams
             Log.e("Debug","File is written");
             fileInputStream.close();
             dos.flush();
             dos.close();
            }
            catch (MalformedURLException ex)
            {
                 Log.e("Debug", "error: " + ex.getMessage(), ex);
            }
            catch (IOException ioe)
            {
                 Log.e("Debug", "error: " + ioe.getMessage(), ioe);
            }
            //------------------ read the SERVER RESPONSE
            try {
                  inStream = new DataInputStream ( conn.getInputStream() );
                  String str;
    
                  while (( str = inStream.readLine()) != null)
                  {
                       Log.e("Debug","Server Response "+str);
                  }
                  inStream.close();
    
            }
            catch (IOException ioex){
                 Log.e("Debug", "error: " + ioex.getMessage(), ioex);
            }
          }
    }
    

    服务器端 (PHP) 代码

    <?php
    // Where the file is going to be placed
    $target_path = "uploads/";
    
    /* Add the original filename to our target path.
    Result is "uploads/filename.extension" */
    $target_path = $target_path . basename( $_FILES['uploadedfile']['name']);
    
    if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
        echo "The file ".  basename( $_FILES['uploadedfile']['name']).
        " has been uploaded";
    } else{
        echo "There was an error uploading the file, please try again!";
        echo "filename: " .  basename( $_FILES['uploadedfile']['name']);
        echo "target_path: " .$target_path;
    }
    ?>
    

    注意事项 1. 确保您的服务器正在运行。 2.您的服务器文件路径应该是正确的。 3. 检查你在服务器中的文件夹写权限。

    以上客户端代码用于音频文件

    您可以将它用于图像,视频也 通过对它进行一些更改,例如

      intent.setType("audio/*");
    

    根据您的要求使用视频/图像并使用它

    用于以下逻辑的压缩

    我偶然发现的一个主要令人讨厌的问题是,我无法使用 Intents 将多个附件发送到 Google Mail 应用程序。最快的解决方法当然是将所有文件压缩成一个 (ZIP)。

    在网上搜索后,我并没有找到太多关于在您的 Android 设备上压缩文件的信息 - 大多数文章都是针对标准 Java 应用程序的,它假定您的所有文件都在您想要压缩的当前目录中。

    所以,我尽我所能创建了我自己的包装类,让您可以轻松地在 Android 中压缩文件!

    这是课程:

      import android.util.Log; 
    import java.io.BufferedInputStream; 
    import java.io.BufferedOutputStream; 
    import java.io.FileInputStream; 
    import java.io.FileOutputStream; 
    import java.util.zip.ZipEntry; 
    import java.util.zip.ZipOutputStream; 
    
    
    public class Compress { 
      private static final int BUFFER = 2048; 
    
      private String[] _files; 
      private String _zipFile; 
    
      public Compress(String[] files, String zipFile) { 
        _files = files; 
        _zipFile = zipFile; 
      } 
    
      public void zip() { 
        try  { 
          BufferedInputStream origin = null; 
          FileOutputStream dest = new FileOutputStream(_zipFile); 
    
          ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest)); 
    
          byte data[] = new byte[BUFFER]; 
    
          for(int i=0; i < _files.length; i++) { 
            Log.v("Compress", "Adding: " + _files[i]); 
            FileInputStream fi = new FileInputStream(_files[i]); 
            origin = new BufferedInputStream(fi, BUFFER); 
            ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1)); 
            out.putNextEntry(entry); 
            int count; 
            while ((count = origin.read(data, 0, BUFFER)) != -1) { 
              out.write(data, 0, count); 
            } 
            origin.close(); 
          } 
    
          out.close(); 
        } catch(Exception e) { 
          e.printStackTrace(); 
        } 
    
      } 
    
    } 
    

    如果这一切对你来说都有意义,那么你可能不会对我下面的解释感兴趣,否则,请继续阅读。 :)

    private static final int BUFFER = 2048; 
    
    private String[] _files; 
    private String _zipFile; 
    

    这些是我为该类声明的属性。

    第一个是 BUFFER(用于读取数据并将其写入 zip 流),第二个是 _files 数组,它将保存所有将被压缩的文件(路径也是如此),第三个是zip 文件的名称(也是路径)。

    public Compress(String[] files, String zipFile) { 
      _files = files; 
      _zipFile = zipFile; 
    } 
    

    这是构造函数,它是在实例化类时调用的第一件事——你将向它传递一个你想要压缩的文件的数组,以及一个包含最终压缩文件名称的字符串.然后它将这些数据保存在属性中,以便在您调用 zip 方法时使用。

    BufferedInputStream origin = null; 
    FileOutputStream dest = new FileOutputStream(_zipFile); 
    
    ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(dest)); 
    
    byte data[] = new byte[BUFFER]; 
    

    接下来我们进入 zip 方法 - 我们要做的第一件事是设置 BufferedInputStream,我们将使用它从文件输入流(文件数组中的每个文件)中读取数据。

    FileOutputStream 创建 zip 文件并设置流,然后我们将其传递给 ZipOutputStream 进行写入。

    如果您想更深入地了解每个对象(类),请在 Google 中快速搜索 FileOutputStream 或 ZipOutputStream。

    for(int i=0; i < _files.length; i++) { 
      Log.v("Compress", "Adding: " + _files[i]); 
    
      FileInputStream fi = new FileInputStream(_files[i]); 
      origin = new BufferedInputStream(fi, BUFFER); 
    
      ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1)); 
      out.putNextEntry(entry); 
    
      int count; 
      while ((count = origin.read(data, 0, BUFFER)) != -1) { 
        out.write(data, 0, count); 
      } 
    
      origin.close(); 
    } 
    
    out.close(); 
    

    这里我们有主循环,它将遍历 _files 数组中的每个文件并将每个文件压缩到 zip 文件中。

    这里我们首先设置一个 FileInputStream 来读取文件 - BufferedInputStream 将管理一次读取的数据量(基于 BUFFER)。

    ZipEntry 用于添加实际的文件/目录结构 - 例如,如果您添加“/mnt/sdcard/data/myzip.zip”,它实际上会在 zip 文件中创建该目录结构,所以如果您只想将文件添加到 zip 的根目录中,您需要将其解析出来。就个人而言,我只是使用 substring 和 lastIndexOf 来抓取最后的文件。

    设置条目后,您可以使用 out.putNextEntry 将其添加到 zip 输出流中。

    现在我们有另一个循环,它将用于读取数据,一次 2048 个字节,并将其写入 zip 输出流(到新的入口位置)。

    最后,我们清理 - 关闭流。

    【讨论】:

    • 但是如何压缩视频?请帮帮我..
    • 谢谢..回复,但我必须减小视频大小?所以,请帮助我...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-01
    • 2021-05-30
    • 2015-11-25
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多