我是Android开发的新手,我无法将视频压缩到Android应用程序中。
因此,请帮助我以编程方式压缩视频并上传到服务器。
我使用FFmpeg但不知道如何正确使用它。请指导我这样做。
答案 0 :(得分:3)
客户端(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.检查服务器中的文件夹写入权限。
以上客户端代码用于AUDIO文件
您也可以将它用于图像和视频 通过做一些改变,如
intent.setType("audio/*");
根据您的要求使用视频/图像并使用它
用于压缩使用逻辑
我偶然发现的一个令人烦恼的问题是,我无法使用Intent向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文件名的字符串将会。然后它将这些数据保存在属性中,以便在调用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用于添加实际的文件/目录结构 - 例如,如果添加&#39; /mnt/sdcard/data/myzip.zip' ;,它实际上会在zip中创建该目录结构文件,所以如果你只想将文件添加到zip的根目录中,你需要解析它。就个人而言,我只是使用substring和lastIndexOf来抓取文件。
设置条目后,您可以使用out.putNextEntry将其添加到zip输出流。
现在我们有另一个循环,它将用于读取数据,一次2048个字节,并将其写入zip输出流(到新的入口位置)。
最后,我们清理 - 关闭溪流。