
Recherche avancée
Médias (1)
-
Bug de détection d’ogg
22 mars 2013, par
Mis à jour : Avril 2013
Langue : français
Type : Video
Autres articles (49)
-
Mise à disposition des fichiers
14 avril 2011, parPar défaut, lors de son initialisation, MediaSPIP ne permet pas aux visiteurs de télécharger les fichiers qu’ils soient originaux ou le résultat de leur transformation ou encodage. Il permet uniquement de les visualiser.
Cependant, il est possible et facile d’autoriser les visiteurs à avoir accès à ces documents et ce sous différentes formes.
Tout cela se passe dans la page de configuration du squelette. Il vous faut aller dans l’espace d’administration du canal, et choisir dans la navigation (...) -
Problèmes fréquents
10 mars 2010, parPHP et safe_mode activé
Une des principales sources de problèmes relève de la configuration de PHP et notamment de l’activation du safe_mode
La solution consiterait à soit désactiver le safe_mode soit placer le script dans un répertoire accessible par apache pour le site -
Mediabox : ouvrir les images dans l’espace maximal pour l’utilisateur
8 février 2011, parLa visualisation des images est restreinte par la largeur accordée par le design du site (dépendant du thème utilisé). Elles sont donc visibles sous un format réduit. Afin de profiter de l’ensemble de la place disponible sur l’écran de l’utilisateur, il est possible d’ajouter une fonctionnalité d’affichage de l’image dans une boite multimedia apparaissant au dessus du reste du contenu.
Pour ce faire il est nécessaire d’installer le plugin "Mediabox".
Configuration de la boite multimédia
Dès (...)
Sur d’autres sites (6204)
-
FFmpeg record and stream
16 janvier 2019, par RobertI’m getting the following error.
E/FFmpeg: Exception while trying to run:
[/data/user/0/com.example.pathways.testipcam/files/ffmpeg, -y, -i,
rtsp://log:pass@IP:port/video.h264, -acodec, copy, -vcodec, copy, -t,
00:03:00,
content://com.example.android.fileprovider/external_files/Android/data/com.example.pathways.testipcam/files/Movies/IPcam_20190116_150628_6019720208966811003.m>kv]
java.io.IOException: Cannot run program "/data/user/0/com.example.pathways.testipcam/files/ffmpeg": error=2, No such >file or directoryOK I’m trying to learn how to record and stream my IP cam on android. I can stream the video in a surface view media player no problem so I then went to the record task. Now I’m a bit lost. I know this is possible as I have read people say they used this to do it.
I started with implamenting
implementation 'nl.bravobit:android-ffmpeg:1.1.5'
But I can’t figure out what I am missing or doing wrong as there aren’t really any tutorials explaining this completely. So hopefully this can be the thread everyone else finds for a solution. I have listed my code below. Exactly what have I got wrong here. It runs and goes to onStart...then right on onFailure.
DO I need to have 2 streams in order to view and watch ? or what the deal.
I know FFmpeg can do that.
"ffmpeg supports multiple outputs created out of the same input(s) in the same process. The usual way to accomplish this is :ffmpeg -i input1 -i input2 \
-acodec … -vcodec … output1 \
-acodec … -vcodec … output2 \"but I have no idea how to sue that.
Anyway, I know I’m kind of close, at least I hope I need a little help on getting over the finish line on this. What have I done wrong, how does this work.Here is what I did, I streamed the video as the app does. no problem
surfaceView = (SurfaceView) findViewById(R.id.videoView);
_surfaceHolder = surfaceView.getHolder();
_surfaceHolder.addCallback(this);
_surfaceHolder.setFixedSize(320, 240);
....
@Override
public void surfaceCreated(SurfaceHolder holder) {
mpPlayerRun();
}
public void mpPlayerRun(){
_mediaPlayer = new MediaPlayer();
_mediaPlayer.setDisplay(_surfaceHolder);
try {
// Specify the IP camera's URL and auth headers.
_mediaPlayer.setDataSource(RTSP_URL);
// Begin the process of setting up a video stream.
_mediaPlayer.setOnPreparedListener(this);
_mediaPlayer.prepareAsync();
}
catch (Exception e) {}
}
...
@Override
public void onPrepared(MediaPlayer mp) {
_mediaPlayer.start();
}OK, so then I created a button to record.
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.IPcamback:
break;
case R.id.IPcamrecord:
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
takeIPvid();
} else {
requestIPCamPermission();
}.....
requested permission then results.
private void requestIPCamPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(this)
.setTitle("Permission needed")
.setMessage("This permission is needed do to android safety protocol")
.setPositiveButton("ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MainActivity.this,
new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, 420);
}
})
.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
})
.create().show();
} else {
ActivityCompat.requestPermissions(this,
new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, 420);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 420) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
takeIPvid();
} else {
Toast.makeText(this, "Permission DENIED", Toast.LENGTH_SHORT).show();
}
.....then I made the file provider and createVideoOutputFile() method and the takeIPvid method.
private File createVideoOutputFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "IPcam_" + timeStamp + "_";
IPstorageDir = getExternalFilesDir(Environment.DIRECTORY_MOVIES);
IPvideo_file = File.createTempFile(
imageFileName, /* prefix */
".mp4", /* suffix */
IPstorageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
String IPmVideoFilename = IPvideo_file.getAbsolutePath();
return IPvideo_file;
}
private void takeIPvid() {
File ipfile = null;
try {
ipfile = createVideoOutputFile();
} catch (IOException e) {
e.printStackTrace();
}
IPvideo_uri = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
ipfile);
String[] cmd = {"-y", "-i", "rtsp://Login:Passord@IP:port/video.h264", "-acodec", "copy", "-vcodec", "copy","-t","00:00:20", IPvideo_uri.toString() };
FFmpeg.getInstance(this).execute(cmd,new ExecuteBinaryResponseHandler(){
@Override
public void onStart() {
super.onStart();
}
@Override
public void onFailure(String message) {
super.onFailure(message);
}
@Override
public void onSuccess(String message) {
super.onSuccess(message);
}
@Override
public void onProgress(String message) {
super.onProgress(message);
}
@Override
public void onFinish() {
super.onFinish();
}
});
} -
Audio & Video not synchronized properly if i merged more videos in mp4parser
1er octobre 2013, par maniyaI have used mp4parser for merging video with dynamic pause and record video capture for max 6 second recording. In preview its working fine when recorded video with minimum pause/record, If i tried with more than 3 pause/record mean the last video file not get merged properly with audio.At the start of the video the sync is ok but at the end the video hanged and audio playing in screen for the remaining file duration about 1sec.
My Recording manager
public class RecordingManager implements Camera.ErrorCallback, MediaRecorder.OnErrorListener, MediaRecorder.OnInfoListener {
private static final String TAG = RecordingManager.class.getSimpleName();
private static final int FOCUS_AREA_RADIUS = 32;
private static final int FOCUS_MAX_VALUE = 1000;
private static final int FOCUS_MIN_VALUE = -1000;
private static final long MINIMUM_RECORDING_TIME = 2000;
private static final int MAXIMUM_RECORDING_TIME = 70 * 1000;
private static final long LOW_STORAGE_THRESHOLD = 5 * 1024 * 1024;
private static final long RECORDING_FILE_LIMIT = 100 * 1024 * 1024;
private boolean paused = true;
private MediaRecorder mediaRecorder = null;
private boolean recording = false;
private FrameLayout previewFrame = null;
private boolean mPreviewing = false;
// private TextureView mTextureView = null;
// private SurfaceTexture mSurfaceTexture = null;
// private boolean mSurfaceTextureReady = false;
//
private SurfaceView surfaceView = null;
private SurfaceHolder surfaceHolder = null;
private boolean surfaceViewReady = false;
private Camera camera = null;
private Camera.Parameters cameraParameters = null;
private CamcorderProfile camcorderProfile = null;
private int mOrientation = -1;
private OrientationEventListener mOrientationEventListener = null;
private long mStartRecordingTime;
private int mVideoWidth;
private int mVideoHeight;
private long mStorageSpace;
private Handler mHandler = new Handler();
// private Runnable mUpdateRecordingTimeTask = new Runnable() {
// @Override
// public void run() {
// long recordingTime = System.currentTimeMillis() - mStartRecordingTime;
// Log.d(TAG, String.format("Recording time:%d", recordingTime));
// mHandler.postDelayed(this, CLIP_GRAPH_UPDATE_INTERVAL);
// }
// };
private Runnable mStopRecordingTask = new Runnable() {
@Override
public void run() {
stopRecording();
}
};
private static RecordingManager mInstance = null;
private Activity currentActivity = null;
private String destinationFilepath = "";
private String snapshotFilepath = "";
public static RecordingManager getInstance(Activity activity, FrameLayout previewFrame) {
if (mInstance == null || mInstance.currentActivity != activity) {
mInstance = new RecordingManager(activity, previewFrame);
}
return mInstance;
}
private RecordingManager(Activity activity, FrameLayout previewFrame) {
currentActivity = activity;
this.previewFrame = previewFrame;
}
public int getVideoWidth() {
return this.mVideoWidth;
}
public int getVideoHeight() {
return this.mVideoHeight;
}
public void setDestinationFilepath(String filepath) {
this.destinationFilepath = filepath;
}
public String getDestinationFilepath() {
return this.destinationFilepath;
}
public void setSnapshotFilepath(String filepath) {
this.snapshotFilepath = filepath;
}
public String getSnapshotFilepath() {
return this.snapshotFilepath;
}
public void init(String videoPath, String snapshotPath) {
Log.v(TAG, "init.");
setDestinationFilepath(videoPath);
setSnapshotFilepath(snapshotPath);
if (!Utils.isExternalStorageAvailable()) {
showStorageErrorAndFinish();
return;
}
openCamera();
if (camera == null) {
showCameraErrorAndFinish();
return;
}
public void onResume() {
Log.v(TAG, "onResume.");
paused = false;
// Open the camera
if (camera == null) {
openCamera();
if (camera == null) {
showCameraErrorAndFinish();
return;
}
}
// Initialize the surface texture or surface view
// if (useTexture() && mTextureView == null) {
// initTextureView();
// mTextureView.setVisibility(View.VISIBLE);
// } else if (!useTexture() && mSurfaceView == null) {
initSurfaceView();
surfaceView.setVisibility(View.VISIBLE);
// }
// Start the preview
if (!mPreviewing) {
startPreview();
}
}
private void openCamera() {
Log.v(TAG, "openCamera");
try {
camera = Camera.open();
camera.setErrorCallback(this);
camera.setDisplayOrientation(90); // Since we only support portrait mode
cameraParameters = camera.getParameters();
} catch (RuntimeException e) {
e.printStackTrace();
camera = null;
}
}
private void closeCamera() {
Log.v(TAG, "closeCamera");
if (camera == null) {
Log.d(TAG, "Already stopped.");
return;
}
camera.setErrorCallback(null);
if (mPreviewing) {
stopPreview();
}
camera.release();
camera = null;
}
private void initSurfaceView() {
surfaceView = new SurfaceView(currentActivity);
surfaceView.getHolder().addCallback(new SurfaceViewCallback());
surfaceView.setVisibility(View.GONE);
FrameLayout.LayoutParams params = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT, Gravity.CENTER);
surfaceView.setLayoutParams(params);
Log.d(TAG, "add surface view to preview frame");
previewFrame.addView(surfaceView);
}
private void releaseSurfaceView() {
if (surfaceView != null) {
previewFrame.removeAllViews();
surfaceView = null;
surfaceHolder = null;
surfaceViewReady = false;
}
}
private void startPreview() {
// if ((useTexture() && !mSurfaceTextureReady) || (!useTexture() && !mSurfaceViewReady)) {
// return;
// }
Log.v(TAG, "startPreview.");
if (mPreviewing) {
stopPreview();
}
setCameraParameters();
resizePreview();
try {
// if (useTexture()) {
// mCamera.setPreviewTexture(mSurfaceTexture);
// } else {
camera.setPreviewDisplay(surfaceHolder);
// }
camera.startPreview();
mPreviewing = true;
} catch (Exception e) {
closeCamera();
e.printStackTrace();
Log.e(TAG, "startPreview failed.");
}
}
private void stopPreview() {
Log.v(TAG, "stopPreview");
if (camera != null) {
camera.stopPreview();
mPreviewing = false;
}
}
public void onPause() {
paused = true;
if (recording) {
stopRecording();
}
closeCamera();
// if (useTexture()) {
// releaseSurfaceTexture();
// } else {
releaseSurfaceView();
// }
}
private void setCameraParameters() {
if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_720P)) {
camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_720P);
} else if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_480P)) {
camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_480P);
} else {
camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
}
mVideoWidth = camcorderProfile.videoFrameWidth;
mVideoHeight = camcorderProfile.videoFrameHeight;
camcorderProfile.fileFormat = MediaRecorder.OutputFormat.MPEG_4;
camcorderProfile.videoFrameRate = 30;
Log.v(TAG, "mVideoWidth=" + mVideoWidth + " mVideoHeight=" + mVideoHeight);
cameraParameters.setPreviewSize(mVideoWidth, mVideoHeight);
if (cameraParameters.getSupportedWhiteBalance().contains(Camera.Parameters.WHITE_BALANCE_AUTO)) {
cameraParameters.setWhiteBalance(Camera.Parameters.WHITE_BALANCE_AUTO);
}
if (cameraParameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
cameraParameters.setRecordingHint(true);
cameraParameters.set("cam_mode", 1);
camera.setParameters(cameraParameters);
cameraParameters = camera.getParameters();
camera.setDisplayOrientation(90);
android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
Log.d(TAG, info.orientation + " degree");
}
private void resizePreview() {
Log.d(TAG, String.format("Video size:%d|%d", mVideoWidth, mVideoHeight));
Point optimizedSize = getOptimizedPreviewSize(mVideoWidth, mVideoHeight);
Log.d(TAG, String.format("Optimized size:%d|%d", optimizedSize.x, optimizedSize.y));
ViewGroup.LayoutParams params = (ViewGroup.LayoutParams) previewFrame.getLayoutParams();
params.width = optimizedSize.x;
params.height = optimizedSize.y;
previewFrame.setLayoutParams(params);
}
public void setOrientation(int ori) {
this.mOrientation = ori;
}
public void setOrientationEventListener(OrientationEventListener listener) {
this.mOrientationEventListener = listener;
}
public Camera getCamera() {
return camera;
}
@SuppressWarnings("serial")
public void setFocusArea(float x, float y) {
if (camera != null) {
int viewWidth = surfaceView.getWidth();
int viewHeight = surfaceView.getHeight();
int focusCenterX = FOCUS_MAX_VALUE - (int) (x / viewWidth * (FOCUS_MAX_VALUE - FOCUS_MIN_VALUE));
int focusCenterY = FOCUS_MIN_VALUE + (int) (y / viewHeight * (FOCUS_MAX_VALUE - FOCUS_MIN_VALUE));
final int left = focusCenterY - FOCUS_AREA_RADIUS < FOCUS_MIN_VALUE ? FOCUS_MIN_VALUE : focusCenterY - FOCUS_AREA_RADIUS;
final int top = focusCenterX - FOCUS_AREA_RADIUS < FOCUS_MIN_VALUE ? FOCUS_MIN_VALUE : focusCenterX - FOCUS_AREA_RADIUS;
final int right = focusCenterY + FOCUS_AREA_RADIUS > FOCUS_MAX_VALUE ? FOCUS_MAX_VALUE : focusCenterY + FOCUS_AREA_RADIUS;
final int bottom = focusCenterX + FOCUS_AREA_RADIUS > FOCUS_MAX_VALUE ? FOCUS_MAX_VALUE : focusCenterX + FOCUS_AREA_RADIUS;
Camera.Parameters params = camera.getParameters();
params.setFocusAreas(new ArrayList() {
{
add(new Camera.Area(new Rect(left, top, right, bottom), 1000));
}
});
camera.setParameters(params);
camera.autoFocus(new AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
Log.d(TAG, "onAutoFocus");
}
});
}
}
public void startRecording(String destinationFilepath) {
if (!recording) {
updateStorageSpace();
setDestinationFilepath(destinationFilepath);
if (mStorageSpace <= LOW_STORAGE_THRESHOLD) {
Log.v(TAG, "Storage issue, ignore the start request");
Toast.makeText(currentActivity, "Storage issue, ignore the recording request", Toast.LENGTH_LONG).show();
return;
}
if (!prepareMediaRecorder()) {
Toast.makeText(currentActivity, "prepareMediaRecorder failed.", Toast.LENGTH_LONG).show();
return;
}
Log.d(TAG, "Successfully prepare media recorder.");
try {
mediaRecorder.start();
} catch (RuntimeException e) {
Log.e(TAG, "MediaRecorder start failed.");
releaseMediaRecorder();
return;
}
mStartRecordingTime = System.currentTimeMillis();
if (mOrientationEventListener != null) {
mOrientationEventListener.disable();
}
recording = true;
}
}
public void stopRecording() {
if (recording) {
if (!paused) {
// Capture at least 1 second video
long currentTime = System.currentTimeMillis();
if (currentTime - mStartRecordingTime < MINIMUM_RECORDING_TIME) {
mHandler.postDelayed(mStopRecordingTask, MINIMUM_RECORDING_TIME - (currentTime - mStartRecordingTime));
return;
}
}
if (mOrientationEventListener != null) {
mOrientationEventListener.enable();
}
// mHandler.removeCallbacks(mUpdateRecordingTimeTask);
try {
mediaRecorder.setOnErrorListener(null);
mediaRecorder.setOnInfoListener(null);
mediaRecorder.stop(); // stop the recording
Toast.makeText(currentActivity, "Video file saved.", Toast.LENGTH_LONG).show();
long stopRecordingTime = System.currentTimeMillis();
Log.d(TAG, String.format("stopRecording. file:%s duration:%d", destinationFilepath, stopRecordingTime - mStartRecordingTime));
// Calculate the duration of video
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(this.destinationFilepath);
String _length = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
if (_length != null) {
Log.d(TAG, String.format("clip duration:%d", Long.parseLong(_length)));
}
// Taking the snapshot of video
Bitmap snapshot = ThumbnailUtils.createVideoThumbnail(this.destinationFilepath, Thumbnails.MICRO_KIND);
try {
FileOutputStream out = new FileOutputStream(this.snapshotFilepath);
snapshot.compress(Bitmap.CompressFormat.JPEG, 70, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
// mActivity.showPlayButton();
} catch (RuntimeException e) {
e.printStackTrace();
Log.e(TAG, e.getMessage());
// if no valid audio/video data has been received when stop() is
// called
} finally {
//
releaseMediaRecorder(); // release the MediaRecorder object
if (!paused) {
cameraParameters = camera.getParameters();
}
recording = false;
}
}
}
public void setRecorderOrientation(int orientation) {
// For back camera only
if (orientation != -1) {
Log.d(TAG, "set orientationHint:" + (orientation + 135) % 360 / 90 * 90);
mediaRecorder.setOrientationHint((orientation + 135) % 360 / 90 * 90);
}else {
Log.d(TAG, "not set orientationHint to mediaRecorder");
}
}
private boolean prepareMediaRecorder() {
mediaRecorder = new MediaRecorder();
camera.unlock();
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(camcorderProfile);
mediaRecorder.setMaxDuration(MAXIMUM_RECORDING_TIME);
mediaRecorder.setOutputFile(this.destinationFilepath);
try {
mediaRecorder.setMaxFileSize(Math.min(RECORDING_FILE_LIMIT, mStorageSpace - LOW_STORAGE_THRESHOLD));
} catch (RuntimeException exception) {
}
setRecorderOrientation(mOrientation);
if (!useTexture()) {
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
}
try {
mediaRecorder.prepare();
} catch (IllegalStateException e) {
releaseMediaRecorder();
return false;
} catch (IOException e) {
releaseMediaRecorder();
return false;
}
mediaRecorder.setOnErrorListener(this);
mediaRecorder.setOnInfoListener(this);
return true;
}
private void releaseMediaRecorder() {
if (mediaRecorder != null) {
mediaRecorder.reset(); // clear recorder configuration
mediaRecorder.release(); // release the recorder object
mediaRecorder = null;
camera.lock(); // lock camera for later use
}
}
private Point getOptimizedPreviewSize(int videoWidth, int videoHeight) {
Display display = currentActivity.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
Point optimizedSize = new Point();
optimizedSize.x = size.x;
optimizedSize.y = (int) ((float) videoWidth / (float) videoHeight * size.x);
return optimizedSize;
}
private void showCameraErrorAndFinish() {
DialogInterface.OnClickListener buttonListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
currentActivity.finish();
}
};
new AlertDialog.Builder(currentActivity).setCancelable(false)
.setTitle("Camera error")
.setMessage("Cannot connect to the camera.")
.setNeutralButton("OK", buttonListener)
.show();
}
private void showStorageErrorAndFinish() {
DialogInterface.OnClickListener buttonListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
currentActivity.finish();
}
};
new AlertDialog.Builder(currentActivity).setCancelable(false)
.setTitle("Storage error")
.setMessage("Cannot read external storage.")
.setNeutralButton("OK", buttonListener)
.show();
}
private void updateStorageSpace() {
mStorageSpace = getAvailableSpace();
Log.v(TAG, "updateStorageSpace mStorageSpace=" + mStorageSpace);
}
private long getAvailableSpace() {
String state = Environment.getExternalStorageState();
Log.d(TAG, "External storage state=" + state);
if (Environment.MEDIA_CHECKING.equals(state)) {
return -1;
}
if (!Environment.MEDIA_MOUNTED.equals(state)) {
return -1;
}
File directory = currentActivity.getExternalFilesDir("vine");
directory.mkdirs();
if (!directory.isDirectory() || !directory.canWrite()) {
return -1;
}
try {
StatFs stat = new StatFs(directory.getAbsolutePath());
return stat.getAvailableBlocks() * (long) stat.getBlockSize();
} catch (Exception e) {
Log.i(TAG, "Fail to access external storage", e);
}
return -1;
}
private boolean useTexture() {
return false;
// return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1;
}
private class SurfaceViewCallback implements SurfaceHolder.Callback {
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.v(TAG, "surfaceChanged. width=" + width + ". height=" + height);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.v(TAG, "surfaceCreated");
surfaceViewReady = true;
surfaceHolder = holder;
startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "surfaceDestroyed");
surfaceViewReady = false;
}
}
@Override
public void onError(int error, Camera camera) {
Log.e(TAG, "Camera onError. what=" + error + ".");
if (error == Camera.CAMERA_ERROR_SERVER_DIED) {
} else if (error == Camera.CAMERA_ERROR_UNKNOWN) {
}
}
@Override
public void onInfo(MediaRecorder mr, int what, int extra) {
if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
stopRecording();
} else if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED) {
stopRecording();
Toast.makeText(currentActivity, "Size limit reached", Toast.LENGTH_LONG).show();
}
}
@Override
public void onError(MediaRecorder mr, int what, int extra) {
Log.e(TAG, "MediaRecorder onError. what=" + what + ". extra=" + extra);
if (what == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {
stopRecording();
}
}
}VideoUtils
public class VideoUtils {
private static final String TAG = VideoUtils.class.getSimpleName();
static double[] matrix = new double[] { 0.0, 1.0, 0.0, -1.0, 0.0, 0.0, 0.0,
0.0, 1.0 };
public static boolean MergeFiles(String speratedDirPath,
String targetFileName) {
File videoSourceDirFile = new File(speratedDirPath);
String[] videoList = videoSourceDirFile.list();
List<track> videoTracks = new LinkedList<track>();
List<track> audioTracks = new LinkedList<track>();
for (String file : videoList) {
Log.d(TAG, "source files" + speratedDirPath
+ File.separator + file);
try {
FileChannel fc = new FileInputStream(speratedDirPath
+ File.separator + file).getChannel();
Movie movie = MovieCreator.build(fc);
for (Track t : movie.getTracks()) {
if (t.getHandler().equals("soun")) {
audioTracks.add(t);
}
if (t.getHandler().equals("vide")) {
videoTracks.add(t);
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
Movie result = new Movie();
try {
if (audioTracks.size() > 0) {
result.addTrack(new AppendTrack(audioTracks
.toArray(new Track[audioTracks.size()])));
}
if (videoTracks.size() > 0) {
result.addTrack(new AppendTrack(videoTracks
.toArray(new Track[videoTracks.size()])));
}
IsoFile out = new DefaultMp4Builder().build(result);
FileChannel fc = new RandomAccessFile(
String.format(targetFileName), "rw").getChannel();
Log.d(TAG, "target file:" + targetFileName);
TrackBox tb = out.getMovieBox().getBoxes(TrackBox.class).get(1);
TrackHeaderBox tkhd = tb.getTrackHeaderBox();
double[] b = tb.getTrackHeaderBox().getMatrix();
tkhd.setMatrix(matrix);
fc.position(0);
out.getBox(fc);
fc.close();
for (String file : videoList) {
File TBRFile = new File(speratedDirPath + File.separator + file);
TBRFile.delete();
}
boolean a = videoSourceDirFile.delete();
Log.d(TAG, "try to delete dir:" + a);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return false;
}
return true;
}
public static boolean clearFiles(String speratedDirPath) {
File videoSourceDirFile = new File(speratedDirPath);
if (videoSourceDirFile != null
&& videoSourceDirFile.listFiles() != null) {
File[] videoList = videoSourceDirFile.listFiles();
for (File video : videoList) {
video.delete();
}
videoSourceDirFile.delete();
}
return true;
}
public static int createSnapshot(String videoFile, int kind, String snapshotFilepath) {
return 0;
};
public static int createSnapshot(String videoFile, int width, int height, String snapshotFilepath) {
return 0;
}
}
</track></track></track></track>my reference code project link is
-
How to get picture buffer data in ffmpeg ?
5 juin 2014, par 4ntoineI’m trying to pass bitmap from ffmpeg to android.
It already works but it’s displaying picture right on surface passed from java to native code.
How can i get frame buffer bitmap data to pass it to java ?I’ve tried to save out_frame buffer data :
unsigned char bmpFileHeader[14] = {'B', 'M', 0,0,0,0, 0,0, 0,0, 54, 0,0,0};
unsigned char bmpInfoHeader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0};
unsigned char bmpPad[3] = {0, 0, 0};
void saveBuffer(int fileIndex, int width, int height, unsigned char *buffer, int buffer_size) {
unsigned char filename[1024];
sprintf(filename, "/storage/sdcard0/3d_player_%d.bmp", fileIndex);
LOGI(10, "saving ffmpeg bitmap file: %d to %s", fileIndex, filename);
FILE *bitmapFile = fopen(filename, "wb");
if (!bitmapFile) {
LOGE(10, "failed to create ffmpeg bitmap file");
return;
}
unsigned char filesize = 54 + 3 * width * height; // 3 = (r,g,b)
bmpFileHeader[2] = (unsigned char)(filesize);
bmpFileHeader[3] = (unsigned char)(filesize >> 8);
bmpFileHeader[4] = (unsigned char)(filesize >> 16);
bmpFileHeader[5] = (unsigned char)(filesize >> 24);
bmpInfoHeader[4] = (unsigned char)(width);
bmpInfoHeader[5] = (unsigned char)(width >> 8);
bmpInfoHeader[6] = (unsigned char)(width >> 16);
bmpInfoHeader[7] = (unsigned char)(width >> 24);
bmpInfoHeader[8] = (unsigned char)(height);
bmpInfoHeader[9] = (unsigned char)(height >> 8);
bmpInfoHeader[10] = (unsigned char)(height >> 16);
bmpInfoHeader[11] = (unsigned char)(height >> 24);
fwrite(bmpFileHeader, 1, 14, bitmapFile);
fwrite(bmpInfoHeader, 1, 40, bitmapFile);
int i;
for (i=0; iplayer;
int stream_no = decoder_data->stream_no;
AVCodecContext * ctx = player->input_codec_ctxs[stream_no];
AVFrame * frame = player->input_frames[stream_no];
AVStream * stream = player->input_streams[stream_no];
int interrupt_ret;
int to_write;
int err = 0;
AVFrame *rgb_frame = player->rgb_frame;
ANativeWindow_Buffer buffer;
ANativeWindow * window;
#ifdef MEASURE_TIME
struct timespec timespec1, timespec2, diff;
#endif // MEASURE_TIME
LOGI(10, "player_decode_video decoding");
int frameFinished;
#ifdef MEASURE_TIME
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timespec1);
#endif // MEASURE_TIME
int ret = avcodec_decode_video2(ctx, frame, &frameFinished,
packet_data->packet);
#ifdef MEASURE_TIME
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timespec2);
diff = timespec_diff(timespec1, timespec2);
LOGI(3, "decode_video timediff: %d.%9ld", diff.tv_sec, diff.tv_nsec);
#endif // MEASURE_TIME
if (ret < 0) {
LOGE(1, "player_decode_video Fail decoding video %d\n", ret);
return -ERROR_WHILE_DECODING_VIDEO;
}
if (!frameFinished) {
LOGI(10, "player_decode_video Video frame not finished\n");
return 0;
}
// saving in buffer converted video frame
LOGI(7, "player_decode_video copy wait");
#ifdef MEASURE_TIME
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timespec1);
#endif // MEASURE_TIME
pthread_mutex_lock(&player->mutex_queue);
window = player->window;
if (window == NULL) {
pthread_mutex_unlock(&player->mutex_queue);
goto skip_frame;
}
ANativeWindow_setBuffersGeometry(window, ctx->width, ctx->height,
WINDOW_FORMAT_RGBA_8888);
if (ANativeWindow_lock(window, &buffer, NULL) != 0) {
pthread_mutex_unlock(&player->mutex_queue);
goto skip_frame;
}
pthread_mutex_unlock(&player->mutex_queue);
int format = buffer.format;
if (format < 0) {
LOGE(1, "Could not get window format")
}
enum PixelFormat out_format;
if (format == WINDOW_FORMAT_RGBA_8888) {
out_format = PIX_FMT_RGBA;
LOGI(6, "Format: WINDOW_FORMAT_RGBA_8888");
} else if (format == WINDOW_FORMAT_RGBX_8888) {
out_format = PIX_FMT_RGB0;
LOGE(1, "Format: WINDOW_FORMAT_RGBX_8888 (not supported)");
} else if (format == WINDOW_FORMAT_RGB_565) {
out_format = PIX_FMT_RGB565;
LOGE(1, "Format: WINDOW_FORMAT_RGB_565 (not supported)");
} else {
LOGE(1, "Unknown window format");
}
avpicture_fill((AVPicture *) rgb_frame, buffer.bits, out_format,
buffer.width, buffer.height);
rgb_frame->data[0] = buffer.bits;
if (format == WINDOW_FORMAT_RGBA_8888) {
rgb_frame->linesize[0] = buffer.stride * 4;
} else {
LOGE(1, "Unknown window format");
}
LOGI(6,
"Buffer: width: %d, height: %d, stride: %d",
buffer.width, buffer.height, buffer.stride);
int i = 0;
#ifdef MEASURE_TIME
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timespec2);
diff = timespec_diff(timespec1, timespec2);
LOGI(1,
"lockPixels and fillimage timediff: %d.%9ld", diff.tv_sec, diff.tv_nsec);
#endif // MEASURE_TIME
#ifdef MEASURE_TIME
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &timespec1);
#endif // MEASURE_TIME
LOGI(7, "player_decode_video copying...");
AVFrame * out_frame;
int rescale;
if (ctx->width == buffer.width && ctx->height == buffer.height) {
// This always should be true
out_frame = rgb_frame;
rescale = FALSE;
} else {
out_frame = player->tmp_frame2;
rescale = TRUE;
}
if (ctx->pix_fmt == PIX_FMT_YUV420P) {
__I420ToARGB(frame->data[0], frame->linesize[0], frame->data[2],
frame->linesize[2], frame->data[1], frame->linesize[1],
out_frame->data[0], out_frame->linesize[0], ctx->width,
ctx->height);
} else if (ctx->pix_fmt == PIX_FMT_NV12) {
__NV21ToARGB(frame->data[0], frame->linesize[0], frame->data[1],
frame->linesize[1], out_frame->data[0], out_frame->linesize[0],
ctx->width, ctx->height);
} else {
LOGI(3, "Using slow conversion: %d ", ctx->pix_fmt);
struct SwsContext *sws_context = player->sws_context;
sws_context = sws_getCachedContext(sws_context, ctx->width, ctx->height,
ctx->pix_fmt, ctx->width, ctx->height, out_format,
SWS_FAST_BILINEAR, NULL, NULL, NULL);
player->sws_context = sws_context;
if (sws_context == NULL) {
LOGE(1, "could not initialize conversion context from: %d"
", to :%d\n", ctx->pix_fmt, out_format);
// TODO some error
}
sws_scale(sws_context, (const uint8_t * const *) frame->data,
frame->linesize, 0, ctx->height, out_frame->data,
out_frame->linesize);
}
if (rescale) {
// Never occurs
__ARGBScale(out_frame->data[0], out_frame->linesize[0], ctx->width,
ctx->height, rgb_frame->data[0], rgb_frame->linesize[0],
buffer.width, buffer.height, __kFilterNone);
out_frame = rgb_frame;
}
// TODO: (4ntoine) frame decoded and rescaled, ready to call callback with frame picture from buffer
int bufferSize = buffer.width * buffer.height * 3; // 3 = (r,g,b);
static int bitmapCounter = 0;
if (bitmapCounter < 10) {
saveBuffer(bitmapCounter++, buffer.width, buffer.height, (unsigned char *)out_frame->data, bufferSize);
}but out_frame is empty and file has header and 0x00 bytes body.
How to get picture buffer data in ffmpeg ?