
Recherche avancée
Médias (1)
-
SPIP - plugins - embed code - Exemple
2 septembre 2013, par
Mis à jour : Septembre 2013
Langue : français
Type : Image
Autres articles (32)
-
HTML5 audio and video support
13 avril 2011, parMediaSPIP uses HTML5 video and audio tags to play multimedia files, taking advantage of the latest W3C innovations supported by modern browsers.
The MediaSPIP player used has been created specifically for MediaSPIP and can be easily adapted to fit in with a specific theme.
For older browsers the Flowplayer flash fallback is used.
MediaSPIP allows for media playback on major mobile platforms with the above (...) -
De l’upload à la vidéo finale [version standalone]
31 janvier 2010, parLe chemin d’un document audio ou vidéo dans SPIPMotion est divisé en trois étapes distinctes.
Upload et récupération d’informations de la vidéo source
Dans un premier temps, il est nécessaire de créer un article SPIP et de lui joindre le document vidéo "source".
Au moment où ce document est joint à l’article, deux actions supplémentaires au comportement normal sont exécutées : La récupération des informations techniques des flux audio et video du fichier ; La génération d’une vignette : extraction d’une (...) -
Support audio et vidéo HTML5
10 avril 2011MediaSPIP utilise les balises HTML5 video et audio pour la lecture de documents multimedia en profitant des dernières innovations du W3C supportées par les navigateurs modernes.
Pour les navigateurs plus anciens, le lecteur flash Flowplayer est utilisé.
Le lecteur HTML5 utilisé a été spécifiquement créé pour MediaSPIP : il est complètement modifiable graphiquement pour correspondre à un thème choisi.
Ces technologies permettent de distribuer vidéo et son à la fois sur des ordinateurs conventionnels (...)
Sur d’autres sites (3404)
-
i wanna trim video in android java
2 mars 2020, par israfilllI used this library implementation ’com.writingminds:FFmpegAndroid:0.3.2’.
But i get an error.CANNOT LINK EXECUTABLE "/data/user/0/com.example.newapplication/files/ffmpeg" : "/data/data/com.example.newapplication/files/ffmpeg" has text relocations (https://android.googlesource.com/platform/bionic/+/master/androg-’changes-for-ndk-developers.md#Text-Relocations-Enforced-for-API-level-23)
is there anyone who know reason ?this is code and i just want to trim(cut) video in time range i want. others is not necessary
public class MainActivity extends AppCompatActivity {
String outPutFile;
Uri filePath, filePathSecond, photoUri, AudioUri;
ProgressDialog progressDialog;
private int REQUEST_TAKE_GALLERY_VIDEO = 110;
private int REQUEST_TAKE_GALLERY_VIDEO_2 = 115;
private int REQUEST_TAKE_GALLERY_PHOTO = 120;
private int REQUEST_TAKE_GALLERY_AUDIO = 130;
private FFmpeg ffmpeg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
}
progressDialog = new ProgressDialog(this);
findViewById(R.id.selectVideo).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Video"), REQUEST_TAKE_GALLERY_VIDEO);
}
});
findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null) {
executeCutVideoCommand(1000, 4 * 1000, filePath);
}
}
});
findViewById(R.id.background).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null && photoUri != null) {
executeBackgroundCommand(filePath, photoUri);
}
}
});
findViewById(R.id.selectPhoto).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Video"), REQUEST_TAKE_GALLERY_PHOTO);
}
});
findViewById(R.id.speed).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null) {
executeSpeedCommand(.9f, filePath);
}
}
});
findViewById(R.id.rotate).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null) {
executeRotateCommand(3, filePath);
}
}
});
findViewById(R.id.selectAudio).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("audio/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Video"), REQUEST_TAKE_GALLERY_AUDIO);
}
});
findViewById(R.id.setAudio).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null && AudioUri != null) {
executeChangeMusicCommand(filePath, AudioUri);
}
}
});
findViewById(R.id.mute).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null) {
executeMuteCommand(filePath);
}
}
});
findViewById(R.id.volume).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null) {
executeVolumeCommand(filePath, .5f);
}
}
});
findViewById(R.id.audio_trim).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (AudioUri != null) {
executeCutAudioCommand(1 * 1000, 10 * 1000, AudioUri);
}
}
});
findViewById(R.id.marge_video).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null && filePathSecond != null)
executeMargeVideoCommand(filePath, filePathSecond);
}
});
findViewById(R.id.selectVideo_2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Video"), REQUEST_TAKE_GALLERY_VIDEO_2);
}
});
findViewById(R.id.ratio_video).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null)
executeRatioCommand(filePath, 2, 5);
}
});
findViewById(R.id.filter_video).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(filePath!=null){
executeFilterCommand(filePath);
}
}
});
loadFFMpegBinary();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_TAKE_GALLERY_VIDEO) {
Uri uri = data.getData();
if (uri != null) {
filePath = uri;
}
}
if (requestCode == REQUEST_TAKE_GALLERY_VIDEO_2) {
Uri uri = data.getData();
if (uri != null) {
filePathSecond = uri;
}
}
if (requestCode == REQUEST_TAKE_GALLERY_PHOTO) {
Uri uri = data.getData();
if (uri != null) {
photoUri = uri;
}
}
if (requestCode == REQUEST_TAKE_GALLERY_AUDIO) {
Uri uri = data.getData();
if (uri != null) {
AudioUri = uri;
}
}
}
private void executeBackgroundCommand(Uri filePath, Uri photoUri) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "set_background_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
String yourRealPathImage = getPath(MainActivity.this, photoUri);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
/* Log.d(TAG, "startTrim: src: " + yourRealPath);
Log.d(TAG, "startTrim: dest: " + dest.getAbsolutePath());
Log.d(TAG, "startTrim: startMs: " + startMs);
Log.d(TAG, "startTrim: endMs: " + endMs);*/
outPutFile = dest.getAbsolutePath();
//String[] complexCommand = {"-i", yourRealPath, "-ss", "" + startMs / 1000, "-t", "" + endMs / 1000, dest.getAbsolutePath()};
String[] complexCommand = {"-i", yourRealPathImage, "-i", yourRealPath
, "-filter_complex", "overlay=(main_w-overlay_w)/2:(main_h-overlay_h)/2", outPutFile};
// String[] complexCommand = {"-i", "" + yourRealPath, "-i", "" +yourRealPathImage, "-filter_complex", "overlay=10:main_h-overlay_h-10",outPutFile};
execFFmpegBinary(complexCommand);
}
// video trim
private void executeCutVideoCommand(int startMs, int endMs, Uri filePath) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "cut_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
/* Log.d(TAG, "startTrim: src: " + yourRealPath);
Log.d(TAG, "startTrim: dest: " + dest.getAbsolutePath());
Log.d(TAG, "startTrim: startMs: " + startMs);
Log.d(TAG, "startTrim: endMs: " + endMs);*/
outPutFile = dest.getAbsolutePath();
//String[] complexCommand = {"-i", yourRealPath, "-ss", "" + startMs / 1000, "-t", "" + endMs / 1000, dest.getAbsolutePath()};
String[] complexCommand = {"-ss",
"" + (startMs / 1000),
"-y",
"-i",
yourRealPath,
"-t",
"" + ((endMs - startMs) / 1000),
"-vcodec",
"mpeg4",
"-b:v",
"2097152",
"-b:a",
"48000",
"-ac",
"2",
"-ar",
"22050",
outPutFile};
execFFmpegBinary(complexCommand);
}
private String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
}
return null;
}
private boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
private boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
private boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
private String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
private void loadFFMpegBinary() {
try {
if (ffmpeg == null) {
ffmpeg = FFmpeg.getInstance(this);
}
ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
@Override
public void onFailure() {
}
@Override
public void onSuccess() {
}
});
} catch (FFmpegNotSupportedException e) {
} catch (Exception e) {
}
}
private void execFFmpegBinary(final String[] command) {
progressDialog.show();
try {
ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
@Override
public void onFailure(String s) {
System.out.println("ssss"+s);
}
@Override
public void onSuccess(String s) {
// Log.d(TAG, "SUCCESS with output : " + s);
Toast.makeText(MainActivity.this, "SUCCESS" + outPutFile, Toast.LENGTH_LONG).show();
}
@Override
public void onProgress(String s) {
}
@Override
public void onStart() {
progressDialog.setMessage("Processing...");
progressDialog.show();
}
@Override
public void onFinish() {
progressDialog.dismiss();
}
});
} catch (Exception e ) {
Toast.makeText(MainActivity.this, "EXCEPTION", Toast.LENGTH_LONG).show();
// do nothing for now
}
}
private void executeSpeedCommand(float speed, Uri filePath) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "speed_change_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
outPutFile = dest.getAbsolutePath();
String[] complexCommand = {"-y", "-i", yourRealPath, "-filter_complex",
"[0:v]setpts=" + (2.5 - speed) + "*PTS[v];[0:a]atempo=" + speed + "[a]", "-map", "[v]", "-map", "[a]", "-b:v", "2097k", "-r", "60", "-vcodec", "mpeg4", outPutFile};
execFFmpegBinary(complexCommand);
}
private void executeRotateCommand(int rotate, Uri filePath) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "speed_rotation_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
outPutFile = dest.getAbsolutePath();
String[] complexCommand = null;
if (rotate == 3) {
complexCommand = new String[]{"-i", yourRealPath, "-filter:v", "transpose=2,transpose=2", outPutFile};
} else {
complexCommand = new String[]{"-i", yourRealPath, "-filter:v", "transpose=" + rotate, outPutFile};
}
execFFmpegBinary(complexCommand);
}
private void executeChangeMusicCommand(Uri filePath, Uri audioUri) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "audio_change_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
String yourRealPathAudio = getPath(MainActivity.this, audioUri);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
outPutFile = dest.getAbsolutePath();
String[] complexCommand = {"-i", yourRealPath, "-i", yourRealPathAudio, "-c:v", "copy", "-c:a", "aac", "-map", "0:v:0", "-map", "1:a:0", "-shortest", outPutFile};
execFFmpegBinary(complexCommand);
}
private void executeMuteCommand(Uri filePath) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "mute_change_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
outPutFile = dest.getAbsolutePath();
String[] complexCommand = {"-i", yourRealPath, "-vcodec", "copy", "-an", outPutFile};
execFFmpegBinary(complexCommand);
}
private void executeVolumeCommand(Uri filePath, float volume) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "volume_change_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
outPutFile = dest.getAbsolutePath();
String[] complexCommand = {"-i", yourRealPath, "-filter:a", "volume=" + volume, outPutFile};
execFFmpegBinary(complexCommand);
}
private void executeCutAudioCommand(int startMs, int endMs, Uri filePath) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "cut_video";
String fileExtn = ".mp3";
String yourRealPath = getPath(MainActivity.this, filePath);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
/* Log.d(TAG, "startTrim: src: " + yourRealPath);
Log.d(TAG, "startTrim: dest: " + dest.getAbsolutePath());
Log.d(TAG, "startTrim: startMs: " + startMs);
Log.d(TAG, "startTrim: endMs: " + endMs);*/
outPutFile = dest.getAbsolutePath();
//String[] complexCommand = {"-i", yourRealPath, "-ss", "" + startMs / 1000, "-t", "" + endMs / 1000, dest.getAbsolutePath()};
String[] complexCommand = {"-ss",
"" + (startMs / 1000),
"-y",
"-i",
yourRealPath,
"-t",
"" + ((endMs - startMs) / 1000),
"-vcodec",
"mpeg4",
"-b:v",
"2097152",
"-b:a",
"48000",
"-ac",
"2",
"-ar",
"22050",
outPutFile};
execFFmpegBinary(complexCommand);
}
private void executeMargeVideoCommand(Uri filePath, Uri filePathSecond) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "marge_change_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
String yourRealPath2 = getPath(MainActivity.this, filePathSecond);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
outPutFile = dest.getAbsolutePath();
String complexCommand[] = {"-y", "-i", yourRealPath, "-i", yourRealPath2, "-strict", "experimental", "-filter_complex",
"[0:v]scale=iw*min(1920/iw\\,1080/ih):ih*min(1920/iw\\,1080/ih), pad=1920:1080:(1920-iw*min(1920/iw\\,1080/ih))/2:(1080-ih*min(1920/iw\\,1080/ih))/2,setsar=1:1[v0];[1:v] scale=iw*min(1920/iw\\,1080/ih):ih*min(1920/iw\\,1080/ih), pad=1920:1080:(1920-iw*min(1920/iw\\,1080/ih))/2:(1080-ih*min(1920/iw\\,1080/ih))/2,setsar=1:1[v1];[v0][0:a][v1][1:a] concat=n=2:v=1:a=1",
"-ab", "48000", "-ac", "2", "-ar", "22050", "-s", "1920x1080", "-vcodec", "libx264", "-crf", "27",
"-q", "4", "-preset", "ultrafast", outPutFile};
execFFmpegBinary(complexCommand);
}
private void executeRatioCommand(Uri filePath, int w, int h) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "ratio_change_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
outPutFile = dest.getAbsolutePath();
// String complexCommand[] = {"-i", yourRealPath,"-r", "15", "-aspect" ,""+w+":"+""+h ,"-strict" ,"-2",outPutFile};
String complexCommand[] = new String[]{"-i", yourRealPath, "-lavf", "[0:v]scale=1920*2:1080*2,boxblur=luma_radius=min(h,w)/20:luma_power=1:chroma_radius=min(cw,ch)/20:chroma_power=1[bg];[0:v]scale=-1:1080[ov];[bg][ov]overlay=(W-w)/2:(H-h)/2,crop=w=1920:h=1080", outPutFile};
execFFmpegBinary(complexCommand);
}
private void executeFilterCommand(Uri filePath) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "filter_change_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
outPutFile = dest.getAbsolutePath();
// String complexCommand[] = {"-i", yourRealPath,"-r", "15", "-aspect" ,""+w+":"+""+h ,"-strict" ,"-2",outPutFile};
String complexCommand[] = { "-i",yourRealPath,"-vf", "split [main][tmp]; [tmp] lutyuv=","y=val*5"," [tmp2]; [main][tmp2] overlay", outPutFile};
execFFmpegBinary(complexCommand);
}}
-
When i used ffmpeg to trim a video ,i observed an error [closed]
6 mars 2020, par israfillli wanna use ffmpeg to trim a video but when i build app i see this I/System.out : ssssCANNOT LINK EXECUTABLE "/data/user/0/com.example.newapplication/files/ffmpeg" : "/data/data/com.example.newapplication/files/ffmpeg" has text relocations (https://android.googlesource.com/platform/bionic/+/master/androg-’changes-for-ndk-developers.md#Text-Relocations-Enforced-for-API-level-23)
why didn’t i use this library
public class MainActivity extends AppCompatActivity {
String outPutFile;
Uri filePath, filePathSecond, photoUri, AudioUri;
ProgressDialog progressDialog;
private int REQUEST_TAKE_GALLERY_VIDEO = 110;
private int REQUEST_TAKE_GALLERY_VIDEO_2 = 115;
private FFmpeg ffmpeg;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},1);
}
progressDialog = new ProgressDialog(this);
findViewById(R.id.selectVideo).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Video"), REQUEST_TAKE_GALLERY_VIDEO);
}
});
findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null) {
executeCutVideoCommand(1000, 4 * 1000, filePath);
}
}
});
findViewById(R.id.marge_video).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (filePath != null && filePathSecond != null)
executeMargeVideoCommand(filePath, filePathSecond);
}
});
findViewById(R.id.selectVideo_2).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setType("video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Video"), REQUEST_TAKE_GALLERY_VIDEO_2);
}
});
findViewById(R.id.filter_video).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(filePath!=null){
executeFilterCommand(filePath);
}
}
});
loadFFMpegBinary();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_TAKE_GALLERY_VIDEO) {
Uri uri = data.getData();
if (uri != null) {
filePath = uri;
}
}
if (requestCode == REQUEST_TAKE_GALLERY_VIDEO_2) {
Uri uri = data.getData();
if (uri != null) {
filePathSecond = uri;
}
}
}
// video trim
private void executeCutVideoCommand(int startMs, int endMs, Uri filePath) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "cut_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
/* Log.d(TAG, "startTrim: src: " + yourRealPath);
Log.d(TAG, "startTrim: dest: " + dest.getAbsolutePath());
Log.d(TAG, "startTrim: startMs: " + startMs);
Log.d(TAG, "startTrim: endMs: " + endMs);*/
outPutFile = dest.getAbsolutePath();
//String[] complexCommand = {"-i", yourRealPath, "-ss", "" + startMs / 1000, "-t", "" + endMs / 1000, dest.getAbsolutePath()};
String[] complexCommand = {"-ss",
"" + (startMs / 1000),
"-y",
"-i",
yourRealPath,
"-t",
"" + ((endMs - startMs) / 1000),
"-vcodec",
"mpeg4",
"-b:v",
"2097152",
"-b:a",
"48000",
"-ac",
"2",
"-ar",
"22050",
outPutFile};
execFFmpegBinary(complexCommand);
}
private String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
// TODO handle non-primary volumes
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{
split[1]
};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
}
return null;
}
private boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is DownloadsProvider.
*/
private boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
/**
* @param uri The Uri to check.
* @return Whether the Uri authority is MediaProvider.
*/
private boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
private String getDataColumn(Context context, Uri uri, String selection,
String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {
column
};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
null);
if (cursor != null && cursor.moveToFirst()) {
final int column_index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(column_index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
private void loadFFMpegBinary() {
try {
if (ffmpeg == null) {
ffmpeg = FFmpeg.getInstance(this);
}
ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
@Override
public void onFailure() {
}
@Override
public void onSuccess() {
}
});
} catch (FFmpegNotSupportedException e) {
} catch (Exception e) {
}
}
private void execFFmpegBinary(final String[] command) {
progressDialog.show();
try {
ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
@Override
public void onFailure(String s) {
System.out.println("ssss"+s);
}
@Override
public void onSuccess(String s) {
// Log.d(TAG, "SUCCESS with output : " + s);
Toast.makeText(MainActivity.this, "SUCCESS" + outPutFile, Toast.LENGTH_LONG).show();
}
@Override
public void onProgress(String s) {
}
@Override
public void onStart() {
progressDialog.setMessage("Processing...");
progressDialog.show();
}
@Override
public void onFinish() {
progressDialog.dismiss();
}
});
} catch (Exception e ) {
Toast.makeText(MainActivity.this, "EXCEPTION", Toast.LENGTH_LONG).show();
// do nothing for now
}
}
private void executeMargeVideoCommand(Uri filePath, Uri filePathSecond) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "marge_change_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
String yourRealPath2 = getPath(MainActivity.this, filePathSecond);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
outPutFile = dest.getAbsolutePath();
String complexCommand[] = {"-y", "-i", yourRealPath, "-i", yourRealPath2, "-strict", "experimental", "-filter_complex",
"[0:v]scale=iw*min(1920/iw\\,1080/ih):ih*min(1920/iw\\,1080/ih), pad=1920:1080:(1920-iw*min(1920/iw\\,1080/ih))/2:(1080-ih*min(1920/iw\\,1080/ih))/2,setsar=1:1[v0];[1:v] scale=iw*min(1920/iw\\,1080/ih):ih*min(1920/iw\\,1080/ih), pad=1920:1080:(1920-iw*min(1920/iw\\,1080/ih))/2:(1080-ih*min(1920/iw\\,1080/ih))/2,setsar=1:1[v1];[v0][0:a][v1][1:a] concat=n=2:v=1:a=1",
"-ab", "48000", "-ac", "2", "-ar", "22050", "-s", "1920x1080", "-vcodec", "libx264", "-crf", "27",
"-q", "4", "-preset", "ultrafast", outPutFile};
execFFmpegBinary(complexCommand);
}
private void executeFilterCommand(Uri filePath) {
File moviesDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
);
String filePrefix = "filter_change_video";
String fileExtn = ".mp4";
String yourRealPath = getPath(MainActivity.this, filePath);
File dest = new File(moviesDir, filePrefix + fileExtn);
int fileNo = 0;
while (dest.exists()) {
fileNo++;
dest = new File(moviesDir, filePrefix + fileNo + fileExtn);
}
outPutFile = dest.getAbsolutePath();
// String complexCommand[] = {"-i", yourRealPath,"-r", "15", "-aspect" ,""+w+":"+""+h ,"-strict" ,"-2",outPutFile};
String complexCommand[] = { "-i",yourRealPath,"-vf", "split [main][tmp]; [tmp] lutyuv=","y=val*5"," [tmp2]; [main][tmp2] overlay", outPutFile};
execFFmpegBinary(complexCommand);
}}
-
Have problems using FFMPEG to save RGB image sequence to .mp4
28 septembre 2021, par ClubsI render some images with OpenGL and need to compose them into a video file. Each of the images is a sequence of uint8_t values representing a sRGB color component (image array looks like ...rgbrgbrgb...)



I know very little about video processing and have no experience with ffmpeg libraries at all. I made a little test program using these sources as reference :



https://ffmpeg.org/doxygen/trunk/encode_video_8c-example.html



How to convert RGB from YUV420p for ffmpeg encoder ?



The test program is supposed to make a video about growing green vertical stripe. I'm just trying to figure out how to make a video using some source of raw RGB data.



Here is my code :



#include <iostream>
#include <vector>
#include <algorithm>

extern "C" {
 #include <libavcodec></libavcodec>avcodec.h>
 #include <libavutil></libavutil>opt.h>
 #include <libavutil></libavutil>imgutils.h>
 #include <libswscale></libswscale>swscale.h>
}

static void encode( AVCodecContext* enc_ctx,
 AVFrame* frame, AVPacket* pkt,
 FILE* outfile )
{
 int ret;
 ret = avcodec_send_frame(enc_ctx, frame);
 if (ret < 0) {
 std::cerr << "Error sending a frame for encoding\n";
 return;
 }
 while (ret >= 0) {
 ret = avcodec_receive_packet(enc_ctx, pkt);
 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
 return;
 else if (ret < 0) {
 fprintf(stderr, "Error during encoding\n");
 exit(1);
 }
 fwrite(pkt->data, 1, pkt->size, outfile);
 av_packet_unref(pkt);
 }
}

static constexpr int w = 1920, h = 1080;
static constexpr float fps = 20.f, time = 5.f;
static constexpr int nFrames = static_cast<int>(fps * time);
static std::vector imageRGB(w * h * 3, 0);

static void UpdateImageRGB()
{
 static int d = 50;
 imageRGB.assign(w * h * 3, 0);
 for (int i = 0; i < h; ++i)
 for ( int j = std::max(0, w / 2 - d);
 j < std::min(w, w / 2 + d);
 ++j )
 {
 imageRGB[(w * i + j) * 3 + 0] = 50;
 imageRGB[(w * i + j) * 3 + 1] = 200;
 imageRGB[(w * i + j) * 3 + 2] = 50;
 }
 d += 5;
}

int main()
{
 int ret = 0;
 auto filename = "test.mp4";

 auto codec = avcodec_find_encoder(AV_CODEC_ID_H264);
 if (!codec) {
 std::cerr << "Codec \"x.264\" not found\n";
 return 1;
 }
 auto c = avcodec_alloc_context3(codec);
 if (!c) {
 std::cerr << "Could not allocate video codec context\n";
 return 1;
 }
 auto pkt = av_packet_alloc();
 if (!pkt) return 1;

 // 1.8 bits / (pixel * frame)
 c->bit_rate = static_cast(1.8f * w * h * fps);
 /* resolution must be a multiple of two */
 c->width = w;
 c->height = h;
 /* frames per second */
 c->time_base = AVRational{ 1, static_cast<int>(fps) };
 c->framerate = AVRational{ static_cast<int>(fps), 1 };

 c->gop_size = 10;
 c->max_b_frames = 1;
 c->pix_fmt = AV_PIX_FMT_YUV420P;
 av_opt_set(c->priv_data, "preset", "slow", 0);
 av_opt_set(c->priv_data, "preset", "slow", 0);

 ret = avcodec_open2(c, codec, NULL);
 if (ret < 0) {
 char str[AV_ERROR_MAX_STRING_SIZE];
 std::cerr << "Could not open codec: "
 << av_make_error_string(str, AV_ERROR_MAX_STRING_SIZE, ret)
 << "\n";
 return 1;
 }

 FILE * f;
 fopen_s(&f, filename, "wb");
 if (!f) {
 std::cerr << "Could not open " << filename << '\n';
 return 1;
 }

 auto frame = av_frame_alloc();
 if (!frame) {
 std::cerr << "Could not allocate video frame\n";
 return 1;
 }
 frame->format = c->pix_fmt;
 frame->width = c->width;
 frame->height = c->height;
 ret = av_frame_get_buffer(frame, 0);
 if (ret < 0) {
 std::cerr << stderr, "Could not allocate the video frame data\n";
 return 1;
 }

 SwsContext* ctx = sws_getContext( w, h, AV_PIX_FMT_RGB24,
 w, h, AV_PIX_FMT_YUV420P,
 0, 0, 0, 0 );

 for (int i = 0; i < nFrames; i++)
 {
 ret = av_frame_make_writable(frame);
 UpdateImageRGB();
 static const uint8_t* rgbData[1] = { &imageRGB[0] };
 static constexpr int rgbLinesize[1] = { 3 * w };
 sws_scale( ctx, rgbData, rgbLinesize, 0, h,
 frame->data, frame->linesize );
 frame->pts = i;
 /* encode the image */
 encode(c, frame, pkt, f);
 }
 encode(c, NULL, pkt, f);

 fclose(f);
 avcodec_free_context(&c);
 av_frame_free(&frame);
 av_packet_free(&pkt);
 return 0;
}
</int></int></int></algorithm></vector></iostream>



The program generates 33.9k video file with further console output :



[libx264 @ 0000020c18681800] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0000020c18681800] profile High, level 5.0, 4:2:0, 8-bit
[libx264 @ 0000020c18681800] frame I:11 Avg QP: 0.00 size: 639
[libx264 @ 0000020c18681800] frame P:74 Avg QP: 0.32 size: 174
[libx264 @ 0000020c18681800] frame B:15 Avg QP: 2.26 size: 990
[libx264 @ 0000020c18681800] consecutive B-frames: 70.0% 30.0%
[libx264 @ 0000020c18681800] mb I I16..4: 100.0% 0.0% 0.0%
[libx264 @ 0000020c18681800] mb P I16..4: 0.6% 0.0% 0.0% P16..4: 2.1% 0.0% 0.0% 0.0% 0.0% skip:97.3%
[libx264 @ 0000020c18681800] mb B I16..4: 0.1% 0.0% 0.0% B16..8: 0.6% 0.0% 0.0% direct: 0.6% skip:98.7% L0:39.8% L1:60.2% BI: 0.0%
[libx264 @ 0000020c18681800] final ratefactor: -46.47
[libx264 @ 0000020c18681800] 8x8 transform intra:0.0%
[libx264 @ 0000020c18681800] direct mvs spatial:0.0% temporal:100.0%
[libx264 @ 0000020c18681800] coded y,uvDC,uvAC intra: 0.0% 0.1% 0.1% inter: 0.0% 0.1% 0.1%
[libx264 @ 0000020c18681800] i16 v,h,dc,p: 99% 0% 1% 0%
[libx264 @ 0000020c18681800] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 0% 0% 100% 0% 0% 0% 0% 0% 0%
[libx264 @ 0000020c18681800] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 46% 0% 54% 0% 0% 0% 0% 0% 0%
[libx264 @ 0000020c18681800] i8c dc,h,v,p: 96% 1% 3% 0%
[libx264 @ 0000020c18681800] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0000020c18681800] ref P L0: 70.2% 0.0% 29.8% 0.0% 0.0%
[libx264 @ 0000020c18681800] kb/s:55.61




- 

- "Media Player Classic" on Windows plays this video but the time slider doesn't move, and the video cannot be fast-forwarded to some frame
- VLC cannot play the video at all. It launches, shows me VLC logo, and time slider (which is unusually big) jumps from left to right, not responding to my clicks
- If I set time = 0.05 to make a video of only 1 frame, I cannot play it even with "Media Player Classic". I want to make an algorithm to convert the arbitrary number of raw RGB images into the video files, even if there's only one image, and with arbitrary image size (that is, width and height may be odd).
- As I said, I don't really understand what am I doing. There are low-level codec settings in lines 83-84. Are they all right ?
- Do I have to manually set a bit rate (line 75) ? Shouldn't it be calculated automatically by the codec ?