реакция-нативное видео вылетает на фоне Android - PullRequest
0 голосов
/ 19 сентября 2018

Я использую видео компонент для воспроизведения аудио:

import React, {Component} from 'react';
import {StyleSheet, View,} from 'react-native';
import Video from 'react-native-video';

export default class App extends Component {
  render() {
    return (
      <View style={styles.container}>
          <Video source={require('./cats.mp3')}
             ref={(ref) => {
                 this.player = ref
         }}
             playInBackground={true}
             playWhenInactive={true}
             onBuffer={this.onBuffer}               
             onEnd={this.onEnd}                      
             onError={this.videoError}               

          />
      </View>
    );
  }
}

При запуске этого на физическом устройстве (Pixel 2 8.1.0) и оставлении приложения в фоновом режиме, воспроизведение аудио останавливается после 3-10минут и приложение вылетает.Воспроизведение может быть возобновлено только после перезапуска приложения.Проблема появляется только в том случае, если к устройству не подключен кабель питания.Когда есть внешнее питание, приложение работает как положено.

Я вытащил это из журнала:

ActivityManager: Killing 20894:com.videotest/u0a419 (adj 700): excessive cpu 53130 during 300068 dur=1762444 limit=2

Похоже, Android отклоняет приложение из-за неправильного использования процессора?Какое может быть решение, чтобы заставить ОС запускать это приложение без перебоев, как это происходит, когда у нас есть внешнее питание?

реакция собственная версия: 0,57 версия реакции-видео-видео: 3.2.1

1 Ответ

0 голосов
/ 15 февраля 2019

Я только что ответил на этот вопрос о проблемах реагирования на видео здесь и скопирую его сюда.

==============================================================

I 'Мне удалось решить эту проблему, по крайней мере, в моем случае, следуя рекомендациям ExoPlayer FAQ по фоновому аудио: https://google.github.io/ExoPlayer/faqs.html#how-do-i-keep-audio-playing-when-my-app-is-backgrounded:

Как сохранить воспроизведение звука, когда мое приложение имеет фоновый режим?

Есть несколько шагов, которые необходимо предпринять, чтобы обеспечить непрерывное воспроизведение звука, когда ваше приложение находится в фоновом режиме:

  1. У вас должен быть запущенный передний планоказание услуг.Это препятствует тому, чтобы система убила ваш процесс, чтобы высвободить ресурсы.
  2. Вам нужно держать WifiLock и WakeLock.Это гарантирует, что система поддерживает беспроводную связь WiFi и процессор.

Важно остановить службу и снять блокировки, как только звук перестанет воспроизводиться.

Чтобы реализовать wakelock и wifilock в RN, я добавил этот пакет: "response-native-wakeful": "^ 0.1.0"

Чтобы реализовать службу переднего плана в RN, я добавил этот пакет: "@voximplant / react-native-foreground-service ":" ^ 1.1.0 "

Обязательно обновите AndroidManifest.xml, как описано в README для этих двух пакетов.

Это приложение демо-репоВ .js есть наглядный пример того, как использовать службу переднего плана: https://github.com/voximplant/react-native-foreground-service-demo/blob/master/App.js:

/**
 * Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved.
 *
 * @format
 * @flow
 * @lint-ignore-every XPLATJSCOPYRIGHT1
 */

import React, {Component} from 'react';
import {Platform, StyleSheet, Text, View, Button} from 'react-native';
import VIForegroundService from "@voximplant/react-native-foreground-service";

type Props = {};
export default class App extends Component<Props> {

    async startService() {
        if (Platform.OS !== 'android') {
            console.log('Only Android platform is supported');
            return;
        }
        if (Platform.Version >= 26) {
            const channelConfig = {
                id: 'ForegroundServiceChannel',
                name: 'Notification Channel',
                description: 'Notification Channel for Foreground Service',
                enableVibration: false,
                importance: 2
            };
            await VIForegroundService.createNotificationChannel(channelConfig);
        }
        const notificationConfig = {
            id: 3456,
            title: 'Foreground Service',
            text: 'Foreground service is running',
            icon: 'ic_notification',
            priority: 0
        };
        if (Platform.Version >= 26) {
            notificationConfig.channelId = 'ForegroundServiceChannel';
        }
        await VIForegroundService.startService(notificationConfig);
    }

    async stopService() {
        await VIForegroundService.stopService();
    }


    render() {
        return (
            <View style={styles.container}>
                <Button title="Start foreground service" onPress={() => this.startService()}/>
                <View style={styles.space}/>
                <Button title="Stop foreground service" onPress={() => this.stopService()}/>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
    },
    space: {
        flex: 0.1
    }
});

Единственное, чего в этом примере не хватает, так это то, что stopService() в начале требуется охрана:

  async stopService() {
    // Only Android platform is supported
    if (Platform.OS !== 'android') {
      return;
    }

    await VIForegroundService.stopService();
  }

В моем приложении, когда пользователь нажимает кнопку «Воспроизведение / Пауза», я делаю это:

    // play or pause the player, then.....

    if (this.isPaused) {
      // release wakelock, wifilock and stop foreground service
      wakeful.release();
      this.stopService();
    } else {
      // acquire wakelock, wifilock and start foreground service
      wakeful.acquire();
      this.startService();
    }

wakeful.release() / wakeful.acquire() можно оставить для iOS, поскольку они просто не работают вэтот случай.

Если кому-то нужна помощь, просто дайте мне знать:)

...