ffmpeg命令无法在Android中使用目录路径的空白区域

时间:2017-04-12 09:21:32

标签: java android ffmpeg whitespace string-formatting

我正在使用FFMPEG库,我希望使用此库旋转视频,如果我file path没有任何white space,则可以正常工作。但在我的情况下,我有视频目录的空白区域(您可以在String commandStr onPreExecute()路径的asynctask public class MainActivity extends AppCompatActivity implements View.OnClickListener{ String workFolder = null; String demoVideoFolder = null; String vkLogPath = null; private boolean commandValidationFailedFlag = false; private Button btnRun; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); GeneralUtils.checkForPermissionsMAndAbove(MainActivity.this, true); setIds(); setListner(); demoVideoFolder = Environment.getExternalStorageDirectory().getAbsolutePath() + "/videokit/"; Log.i(Prefs.TAG, getString(R.string.app_name) + " version: " + GeneralUtils.getVersionName(getApplicationContext()) ); workFolder = getApplicationContext().getFilesDir().getAbsolutePath() + "/"; vkLogPath = workFolder + "vk.log"; GeneralUtils.copyLicenseFromAssetsToSDIfNeeded(this, workFolder); GeneralUtils.copyDemoVideoFromAssetsToSDIfNeeded(this, demoVideoFolder); int rc = GeneralUtils.isLicenseValid(getApplicationContext(), workFolder); Log.i(Prefs.TAG, "License check RC: " + rc); } private void setListner() { btnRun.setOnClickListener(this); } private void setIds() { try { btnRun = (Button)findViewById(R.id.btnRun); } catch (Exception e) { e.printStackTrace(); } } @Override public void onClick(View view) { switch (view.getId()){ case R.id.btnRun: Log.i(Prefs.TAG, "run clicked."); if (GeneralUtils.checkIfFileExistAndNotEmpty(workFolder)) { new TranscdingBackground(MainActivity.this).execute(); } else { Toast.makeText(getApplicationContext(), workFolder + " not found", Toast.LENGTH_LONG).show(); } break; } } public class TranscdingBackground extends AsyncTask<String, Integer, Integer> { ProgressDialog progressDialog; Activity _act; String commandStr; public TranscdingBackground (Activity act) { _act = act; } @Override protected void onPreExecute() { // commandStr = "ffmpeg -y -i /storage/emulated/0/WhatsApp/Media/in.mp4 -vf rotate=270*(PI/180) /sdcard/videokit/out.mp4"; commandStr = "ffmpeg -y -i /storage/emulated/0/WhatsApp/Media/WhatsApp Video/in.mp4 -vf rotate=270*(PI/180) /sdcard/videokit/out.mp4"; progressDialog = new ProgressDialog(_act); progressDialog.setMessage("FFmpeg4Android Transcoding in progress..."); progressDialog.show(); } protected Integer doInBackground(String... paths) { Log.i(Prefs.TAG, "doInBackground started..."); // delete previous log boolean isDeleted = GeneralUtils.deleteFileUtil(workFolder + "/vk.log"); Log.i(Prefs.TAG, "vk deleted: " + isDeleted); PowerManager powerManager = (PowerManager)_act.getSystemService(Activity.POWER_SERVICE); PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "VK_LOCK"); Log.d(Prefs.TAG, "Acquire wake lock"); wakeLock.acquire(); LoadJNI vk = new LoadJNI(); try { vk.run(GeneralUtils.utilConvertToComplex(commandStr), workFolder, getApplicationContext()); // copying vk.log (internal native log) to the videokit folder GeneralUtils.copyFileToFolder(vkLogPath, demoVideoFolder); } catch (CommandValidationException e) { Log.e(Prefs.TAG, "vk run exeption.", e); commandValidationFailedFlag = true; } catch (Throwable e) { Log.e(Prefs.TAG, "vk run exeption.", e); } finally { if (wakeLock.isHeld()) wakeLock.release(); else{ Log.i(Prefs.TAG, "Wake lock is already released, doing nothing"); } } Log.i(Prefs.TAG, "doInBackground finished"); return Integer.valueOf(0); } protected void onProgressUpdate(Integer... progress) { } @Override protected void onCancelled() { Log.i(Prefs.TAG, "onCancelled"); //progressDialog.dismiss(); super.onCancelled(); } @Override protected void onPostExecute(Integer result) { Log.i(Prefs.TAG, "onPostExecute"); progressDialog.dismiss(); super.onPostExecute(result); // finished Toast String rc = null; if (commandValidationFailedFlag) { rc = "Command Vaidation Failed"; } else { rc = GeneralUtils.getReturnCodeFromLog(vkLogPath); } final String status = rc; MainActivity.this.runOnUiThread(new Runnable() { public void run() { Toast.makeText(MainActivity.this, status, Toast.LENGTH_LONG).show(); if (status.equals("Transcoding Status: Failed")) { Toast.makeText(MainActivity.this, "Check: " + vkLogPath + " for more information.", Toast.LENGTH_LONG).show(); } } }); } } } 方法中查看完整路径,然后它根本不起作用。我也看到过像this这样的问题,还有一些问题,但不知道如何正确解决它。下面是我的MainActivity.class代码

onPreExecute()

此处with open(sys.argv[1]) as inputfile: for line in inputfile: print(line) 方法我已经提供了视频文件路径。

2 个答案:

答案 0 :(得分:0)

因为你进行了命令行调用,所以你需要这些:

  • 转义一些特殊字符(就像您在命令行中所需要的那样)

  • 引用文件名(比你需要在文件名中转义引号)

答案 1 :(得分:0)

只需将命令从String转换为ArrayList,如下所示:

commandStr = "ffmpeg -y -i /storage/emulated/0/WhatsApp/Media/WhatsApp Video/in.mp4 -vf rotate=270*(PI/180) /sdcard/videokit/out.mp4";

ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("ffmpeg");
            arrayList.add("-y");
            arrayList.add("-i");
            arrayList.add("/storage/emulated/0/WhatsApp/Media/WhatsApp Video/in.mp4");
            arrayList.add("-vf");
            arrayList.add("rotate=270*(PI/180)");
            arrayList.add("/sdcard/videokit/out.mp4");

并更改你的vk.run();方法如下:

vk.run(GeneralUtils.utilConvertToComplex(commandStr), workFolder, getApplicationContext());

 vk.run(arrayList.toArray(new String[arrayList.size()]), workFolder, getApplicationContext());