Skip to content
This repository was archived by the owner on May 30, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Android applications. It depends on the
[android-ffmpeg](https://github.com/guardianproject/android-ffmpeg) project to
provide the ffmpeg binary.

New ffmpeg binary has be provided from [android-ffmpeg](http://writingminds.github.io/ffmpeg-android/) & [ffmpeg-android-java](https://github.com/WritingMinds/ffmpeg-android-java)
FFmpeg version was update to n2.4.2.


For ease of developer use, we've included the FFMPEG and Sox binaries in the project,
however, we strongly recommend you compile them yourselves using the steps below.

Expand Down
25 changes: 25 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 19
buildToolsVersion "23.0.2"

defaultConfig {
minSdkVersion 14
targetSdkVersion 15
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}

}
dependencies {
compile 'com.google.code.gson:gson:2.4'
compile 'com.jakewharton:butterknife:6.0.0'
compile 'com.googlecode.mp4parser:isoparser:1.1.7'
// compile project(':imagevideo')
}
33 changes: 33 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.ffmpeg.android"
android:versionCode="1"
android:versionName="1.0">

<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="15" />

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<activity
android:name="com.code.MainActivity"
android:screenOrientation="portrait"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>


</manifest>
13 changes: 13 additions & 0 deletions app/src/main/java/com/code/Config.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.code;

/**
* @author Chad
* @title com.code
* @description
* @modifier
* @date
* @since 16/6/1 下午9:19
**/
public class Config {
public static String SYSTEM_DEFAULT_FONT_PATH = "/system/fonts/DroidSansFallback.ttf";
}
63 changes: 63 additions & 0 deletions app/src/main/java/com/code/DialogItem.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.code;

/**
* MovieClip下的对话项.
* 原始JSON:
* <p>
* {
* * dialog_id : 922045
* role_id : 646
* content_en : Mom, what happened on the plane. I'm sorry.
* content_cn : 妈妈,飞机上的事。我很抱歉。
* time_begin : 700
* time_end : 6200
* fea : http://www.mofunenglish.com/storage/pool0/text/26/53/20150130195314734526001421.fea
* fea_v2 : http://www.mofunenglish.com/storage/pool0/text/114/9/201503251350216963090011373528.fea
* fea_content : Mom, what happened on the plane. I'm sorry.
* fea_byte : 9009
* fea_v2_byte : 9025
* expl_count : 0
* }
* </p>
* Created by Administrator on 13-8-17.
*/
public class DialogItem {


public long dialog_id;
public int role_id;
public String content_en;
public String content_cn;
public int time_begin;
public int time_end;
public String fea;
public String fea_v2;
public String fea_content;
public int fea_byte;
public int fea_v2_byte;
public int expl_count;

/**
* 获取对应文件路径
*
* @return
*/
public String getMp3FilePath() {
return "/storage/emulated/0/.mofunshow/records" + "/" + this.dialog_id + ".mp3";
}

public String getRecordFilePath() {
return "/storage/emulated/0/.mofunshow/records" + "/" + this.dialog_id + ".wav";
}

/**
* 判断是否属于某角色,若传入0则认为是全角色,返回true
*
* @param roleId
* @return
*/
public boolean isBelongToRole(long roleId) {
return (roleId <= 0) || (roleId > 0
&& roleId == role_id);
}
}
53 changes: 53 additions & 0 deletions app/src/main/java/com/code/FileUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.code;


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
* Created by Administrator on 13-8-19.
*/
public class FileUtil {


public static boolean writeJsonFile(String file_name, String json_content) {
FileOutputStream fout = null;

try {
fout = new FileOutputStream(file_name);
byte[] bytes = json_content.getBytes();
fout.write(bytes);

} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
if (fout != null) {
try {
fout.flush();
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return true;
}

public static String readJsonFile(String file_name) {
String json_content = "";
try {
FileInputStream fin = new FileInputStream(file_name);
int length = fin.available();
byte[] buffer = new byte[length];
fin.read(buffer);
json_content = new String(buffer, "UTF-8");
fin.close();
} catch (Exception e) {
e.printStackTrace();
return json_content;
}
return json_content;
}
}
144 changes: 144 additions & 0 deletions app/src/main/java/com/code/MainActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package com.code;

import android.app.Activity;
import android.graphics.Bitmap;
import android.media.MediaMetadataRetriever;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import org.ffmpeg.android.R;
import org.ffmpeg.android.test.MixTest;

import java.io.File;
import java.io.FileOutputStream;

import butterknife.ButterKnife;
import butterknife.InjectView;

/**
* @author Chad
* @title com.code
* @description
* @modifier
* @date
* @since 16/5/31 上午12:04
**/
public class MainActivity extends Activity {

@InjectView(R.id.text_mix)
Button textMix;
String mp4FilePath = "/storage/emulated/0/.mofunshow/movies/90331/20160529171913002801000325.mp4";
String bgMp3FilePath = "/storage/emulated/0/.mofunshow/movies/90331/20160520191953876045000830.aac";
String jsonFilePath = "/storage/emulated/0/.mofunshow/movies/90331/20160520192149267651000519.json";
String bgWavFilePath = "/storage/emulated/0/.mofunshow/movies/90331/2015082214101800000358814.wav";
String mp4OutPath = "/storage/emulated/0/.mofunshow/movies/90331/test_out.mp4";
String mp4AllPath = "/storage/emulated/0/.mofunshow/movies/90331/test_out_all.mp4";
String pngPath = "/storage/emulated/0/.mofunshow/movies/90331/1.png";
String pngTempPath = "/storage/emulated/0/.mofunshow/movies/90331/temp.png";
String tempPath = "/storage/emulated/0/ffmpeg/";
@InjectView(R.id.test_merge)
Button testMerge;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
ButterKnife.inject(this);
new File(tempPath).mkdirs();
File[] files = new File("/system/fonts/").listFiles();
for (File file : files) {
String fileName = file.getName().toLowerCase();
if (fileName.contains("miui")) {
if (fileName.toLowerCase().equals("miui-regular")) {
Config.SYSTEM_DEFAULT_FONT_PATH = file.getAbsolutePath();
break;
}
Config.SYSTEM_DEFAULT_FONT_PATH = file.getAbsolutePath();
break;
}
}
textMix.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// List<DialogItem> dialog_list;
// dialog_list = new Gson().fromJson(FileUtil.readJsonFile(jsonFilePath), new TypeToken<ArrayList<DialogItem>>() {}.getType());
// try {
// MixTest.test(tempPath,mp4FilePath,bgMp3FilePath,new Clip(mp4OutPath),getApplicationContext());
// } catch (Exception e) {
// e.printStackTrace();
// }

// try {
// List<String> list = new ArrayList<String>();
// list.add(getImageFileFromVideo(mp4FilePath,pngTempPath));
// MixTest.testJpegToMp4(mp4FilePath,tempPath,list,mp4OutPath,getApplicationContext());
// } catch (Exception e) {
// e.printStackTrace();
// }
try {
MixTest.testMakeLastFrameFilter(getImageFileFromVideo(mp4FilePath, pngTempPath), getTimeLengthFromVideo(mp4FilePath), mp4FilePath, tempPath, mp4OutPath, getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}

}
});
testMerge.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
// MixTest.testMergeMp4(mp4FilePath, mp4OutPath, tempPath, mp4AllPath, getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
}
});

}

public Bitmap getBitmapsFromVideo(String mp4FilePath) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(mp4FilePath);
// 取得视频的长度(单位为毫秒)
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
// 取得视频的长度(单位为秒)
int seconds = Integer.valueOf(time) / 1000;
// 得到每一秒时刻的bitmap比如第一秒,第二秒
bitmap = retriever.getFrameAtTime(seconds * 1000 * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
return bitmap;
}

public long getTimeLengthFromVideo(String mp4FilePath) {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(mp4FilePath);
// 取得视频的长度(单位为毫秒)
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
// 取得视频的长度(单位为秒)
int milins = Integer.valueOf(time);
return milins;
}

public String getImageFileFromVideo(String mp4FilePath, String outPath) {
Bitmap bitmap = null;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(mp4FilePath);
// 取得视频的长度(单位为毫秒)
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
// 取得视频的长度(单位为秒)
int millSeconds = Integer.valueOf(time);
int seconds = millSeconds / 1000;
// 得到每一秒时刻的bitmap比如第一秒,第二秒
bitmap = retriever.getFrameAtTime(millSeconds * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(outPath);
bitmap.compress(Bitmap.CompressFormat.PNG, 80, fos);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
return outPath;
}
}
Loading