bindProcessToNetwork не работает с ffmpeg в Android
Я использую FFmpeg для потоковой передачи видео с камеры (которая подключена через Wi-Fi без подключения к Интернету) на другой сервер, и я хочу сделать процесс потоковой передачи через сотовые данные. Как я уже подключен к Wi-Fi и использовать сотовые данные одновременно bindProcessToNetwork()
, Перед выполнением команды ffmpeg я сделал следующее
final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder req = new NetworkRequest.Builder();
req.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
req.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
cm.requestNetwork(req.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
//here you can use bindProcessToNetwork
//cm.getNetworkInfo(network);
if (cm.getNetworkInfo(network).getType() == ConnectivityManager.TYPE_MOBILE) {
cm.bindProcessToNetwork(network);
}
}
});
в большинстве случаев он работает нормально, например, веб-браузер работает правильно, используя сотовые данные, при подключении к Wi-Fi, но когда я пытаюсь выполнить любую команду ffmpeg, она не работает.
1 ответ
bindProcessToNetwork вызывает netd для привязки текущего процесса к выбранной сети. В ffmpeg-android-java двоичный файл ffmpeg выполняется с использованием Runtime.getRuntime(). Exec (String). Следовательно, ffmpeg фактически работает как отдельный дочерний процесс. NETd не связывает автоматически дочерние процессы с той же сетью, что и их родительский процесс, поэтому вы обнаружите, что ffmpeg не наследует эту конфигурацию. Между тем, другие аспекты вашего приложения, такие как WebView, URLConnection и т. Д., Которые все выполняются в вашем процессе, будут использовать выбранную вами сеть, как и ожидалось.
Чтобы решить эту проблему, у вас есть несколько вариантов (от самых простых до самых сложных):
- Измените исходный код ffmpeg-android-java, добавив параметр командной строки для ffmpeg, который определяет сеть, которую он должен использовать (с беглого взгляда я не вижу никакой поддержки для этого в ffmpeg)
- Найдите утилиту командной строки, которая может принудительно запустить двоичный файл ffmpeg в нужную сеть (может потребоваться root)
- Перестройте ffmpeg, чтобы добавить поддержку нативных сокетов, привязанных к сети по вашему выбору.
- Непосредственно вызов netd для установки сети по умолчанию для нового процесса ffmpeg (вероятно, потребуется root)