FFmpeg executable Chmod permission

2019-05-28 08:25发布

问题:

Trying to run FFmpeg command using executable file stored in Raw folder eclipse for android app. I am getting permission denied error and not able to resize video. How can i give right permissions from my java file.

回答1:

put this code in a static class or wherever you want:

public static void installBinaryFromRaw(Context context, int resId, File file) {
    final InputStream rawStream = context.getResources().openRawResource(resId);
    final OutputStream binStream = getFileOutputStream(file);

    if (rawStream != null && binStream != null) {
        pipeStreams(rawStream, binStream);

        try {
            rawStream.close();
            binStream.close();
        } catch (IOException e) {
            Log.e(TAG, "Failed to close streams!", e);
        }       

        doChmod(file, 777);
    }       
}
public static OutputStream getFileOutputStream(File file) {
    try {
        return new FileOutputStream(file);
    } catch (FileNotFoundException e) {
        Log.e(TAG, "File not found attempting to stream file.", e);
    }
    return null;
}

public static void pipeStreams(InputStream is, OutputStream os) {
    byte[] buffer = new byte[IO_BUFFER_SIZE];
    int count;
    try {
        while ((count = is.read(buffer)) > 0) {
            os.write(buffer, 0, count);
        }
    } catch (IOException e) {
        Log.e(TAG, "Error writing stream.", e);
    }
}
public static void doChmod(File file, int chmodValue) {
    final StringBuilder sb = new StringBuilder();
    sb.append("chmod");
    sb.append(' ');
    sb.append(chmodValue);
    sb.append(' ');
    sb.append(file.getAbsolutePath());

    try {
        Runtime.getRuntime().exec(sb.toString());
    } catch (IOException e) {
        Log.e(TAG, "Error performing chmod", e);
    }
}

And call it with this code:

private void installFfmpeg() {
    File ffmpegFile = new File(getCacheDir(), "ffmpeg");
    mFfmpegInstallPath = ffmpegFile.toString();
    Log.d(TAG, "ffmpeg install path: " + mFfmpegInstallPath);

    if (!ffmpegFile.exists()) {
        try {
            ffmpegFile.createNewFile();
        } catch (IOException e) {
            Log.e(TAG, "Failed to create new file!", e);
        }
        Utils.installBinaryFromRaw(this, R.raw.ffmpeg, ffmpegFile);
    }else{
        Log.d(TAG, "It was already installed");
    }

    ffmpegFile.setExecutable(true);
    Log.d(TAG, String.valueOf(ffmpegFile.canExecute()));
}

Hope it´s useful!!



回答2:

Your Android app must have permissions to read and write to storage, in AndroidManifest.xml:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />.

Another caveat is the path, /storage/emulated/0/ is not available on all devices, you should use Environment.getExternalStorageDirectory() to find the actual path.

Finally, there is an easy workaround instead of extracting ffmpeg from raw folder, rename ffmpeg to lib...ffmpeg...so and put it into directory libs/armeabi in your project.

Naturally, you will later run Runtime.getRuntime().exec(getContext().getApplicationInfo().nativeLibraryDir + "/lib...ffmpeg...so" +whatever)

System installer will unpack the executable into /data/data/your.package.full.name/lib for you automagically.