7

このコード'video-trimmer'に基づいてビデオをトリミングするために ffmpeg.c を呼び出そうとしています。そのため、アクティビティ (ネイティブ ライブラリをロードして使用するアクティビティ) を実行しようとすると、最初に trin をクリックすると動作し、ビデオをトリミングできますが、もう一度実行しようとするとクラッシュします (アプリケーションの再起動でのみ動作します) )。

そのため、この問題の解決策を探すのに 3 日間を費やしました。ほとんどの回答は、ffmpeg.c の静的変数の問題であり、クラスをロードおよびアンロードする lib を作成すると問題が解決すると述べています ( answer1answer2 )。そのため、回答に基づくソリューションとこのgithub リポジトリをビデオ トリマー プロジェクトに適用しようとしましたが、すべての試みが失敗しました。

この問題を修正する「ビデオ トリマー」プロジェクトのフォークについて知っている人はいますか? または、 「ビデオトリマー」プロジェクトでソリューションを実装する方法の段階的な回答を誰かが提供できますか(Web 上のすべてのソリューションに従って、そのプロジェクトにそれらを適用しようとしたが、運がなかったからです)。

4

4 に答える 4

2

the problem seems to be with the initialized values (some variables are declared as global static vars, presumably for ease of access but breaks OOP principles and causes us problems like you're facing), however, there are a few ways round this that I can think of:

  • write a quick function to manually set the static vars back to their correct init values (quick and dirty but works). A list of methods which should not be allowed to fire off as and when they please follows:
    • avcodec_register_all(), avdevice_register_all(), av_register_all()
    • avcodec_find_encoder(), avcodec_find_decoder(), av_find_stream_info()
    • avcodec_open(), avcodec_close()
      • these could be wrapped in a boolean controlled method for example so that if they have run previously they cannot run again.
  • another way to control things is to manually force the variable values (by use of a class or struct to control the ffmpeg global vars) that are being re-initialised on subsequent runs, for example on running the method which currently causes the code to fail, the first step could be to manually set the variables back to their default settings so that they run correctly as at the moment I suspect you have data remaining resident between iterations, and thats what is causing problems.
  • you could utilse mutexes to ensure that the aforementioned methods behave more responsibly when used with threads.

Addendum:

  • also (at the C level) use libffmpeginvoke in preference to libffmpeg if you are going to invoke main() multiple times
  • forcibly invoke Garbage Collection (yep this is another 'ugly' fix) on the call to load the ffmpeg lib, which would then clean things up allowing you to call another instance

Let me know if you need something more in-depth: I can try making a test framework to replicate your problems and see where I get, although that needs access to my home PC as when I am at work I have no Android SDK.

于 2013-01-16T15:33:11.590 に答える
1

実装したコードまたはその一部を提供してください。クラッシュログも参考になります。

ヒント: ffmpeg オブジェクト/スレッドを初期化します。次に、コールバック インターフェイスを使用します。VideoTrimer が終了したら、コールバックを行います。そのコールバックで、ffmpeg オブジェクト/スレッドの破棄/強制終了を呼び出します。

このリンクが役立つかもしれません。

私は最近、github の「android-ffmpeg-java」プロジェクトを使用しました。これは動作するライブラリであり、保証できます。作業を行うラッパー (テスト アプリケーション) を実装するだけです。
ソースについては、このリンクを確認してください: android-ffmpeg-java
たとえば、このリンクを確認してください: android-ffmpeg-cmdline。これで解決できるかどうかを確認してください。

于 2013-01-04T11:48:01.277 に答える
0

やや粗雑ですが、潜在的な回避策は、サービスからffmpegを利用/リンクすることです(とにかくそれを行う方がよいでしょう)。これは、クライアントアクティビティではなく独自のプロセスで実行するようにマニフェストで宣言されています。次に、タスクが完全に終了したときに、必要に応じてネイティブの exit() を呼び出して、そのプロセス自体を終了させます。Android はそのようなことが起こるのを特に好まないでしょう - それは良い習慣ではありません - しかし、あなたはおそらくそれを機能させることができます.

ライブラリを再設計して、それ自体を新しい状態にリセットできるようにする (または完全にコンテキストに合わせることさえできる) 方がよいでしょうが、巨大なレガシー コードベースの場合、大規模なプロジェクトになる可能性があります。

于 2013-01-16T18:35:49.553 に答える
0

これが役立つかどうかはわかりませんが、C ファイルには通常、使用できるヘッダーがあります。

ifndef

以下を参照してください: http://www.cprogramming.com/reference/preprocessor/ifndef.html

その構文を使用して、関連する .h ファイルの宣言をサンドウィッチし、複数のインポートによってインポート コードでクラッシュが発生しないようにします。

幸運を!

編集:わかりました、それはffmpegを.soファイルに再コンパイルすることを意味するようです。コードベースで上記のメカニズムがあることを確認し、何らかの理由で 2 回読み込まれていないことを確認してください。

于 2013-01-16T17:18:08.540 に答える