我正在实现用于音频播放的视频组件:
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因为滥用cpu而拒绝了这个应用程序?什么样的解决方案可以迫使操作系统允许这个应用程序在没有中断的情况下运行,就像我们拥有外部电源时一样?
本机版本: 0.57版本-本机视频版本: 3.2.1
发布于 2019-02-15 09:12:30
我刚刚回答了这个问题的反应-本机-视频问题这里,并将复制在这里。
=========================================================
我已经设法解决了这个问题,至少在我的用例中,我遵循了ExoPlayer FAQ的背景音频指南:https://google.github.io/ExoPlayer/faqs.html#how-do-i-keep-audio-playing-when-my-app-is-backgrounded
当我的应用程序处于后台时,我如何保持音频播放? 当您的应用程序处于后台时,您需要采取以下几个步骤来确保音频的持续播放:
重要的是,您停止服务,并释放锁,一旦音频不再被播放。
为了在RN中实现wakelock和wifilock,我添加了这个包:“react-原生-wakeful”:"^0.1.0“
为了在RN中实现前台服务,我添加了这个包:"@voximplant/react-native-foreground-service":"^1.1.0“
确保按照这两个包的自述更新AndroidManifest.xml。
这个演示回购的App.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,因为在这种情况下,它们只是没有操作。
如果有人需要帮助,请告诉我:)
https://stackoverflow.com/questions/52400385
复制相似问题