最近帮朋友做一下小的app,其中一个功能有以下要求
- 根据搜索结果返回音频列表
- 音频播放完毕自动停止
- 播放一个音频的时候,暂停其他播放中的音频
react-native-video模块安装教程
react-native-video项目地址
npm install --save react-native-video
react-native link react-native-video
#import "AppDelegate.h"
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <AVFoundation/AVFoundation.h>
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSURL *jsCodeLocation;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"OnlineTravel"
initialProperties:nil
launchOptions:launchOptions];
rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
UIViewController *rootViewController = [UIViewController new];
rootViewController.view = rootView;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
@end
页面源码
import React, {Component} from 'react';
import {
Image,
StyleSheet,
Text,
View,
ScrollView,
Alert,
TouchableOpacity,
TextInput, TouchableHighlight, Dimensions,
} from 'react-native';
import Nav from './compenent/Nav';
import Video from 'react-native-video';
const start = require('./img/start.png');
const starting = require('./img/starting.png');
const {height, width} = Dimensions.get('window');
import {URL} from './Common';
const tra = require('./img/tran.png');
const REQUEST_URL = URL + "index.php?m=&c=Index&a=getTranslate";
export default class Translation extends Component {
constructor(props) {
super(props);
this.state = {
text: "",
data: [],
loaded: false,
rate: 0,
first_load: true
};
this.__jump = this.__jump.bind(this);
this.renderAudio = this.renderAudio.bind(this);
this.fetchData = this.fetchData.bind(this);
}
__jump(page) {
this.props.__jump(page);
}
componentDidMount() {
if (!this.state.first_load) {
this.fetchData()
}
}
fetchData() {
let url = REQUEST_URL;
let formData = new FormData();
formData.append("destination", this.state.text);
fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'multipart/form-data',
},
body: formData
})
.then((response) => response.json())
.then((responseData) => {
if (responseData.status) {
this.setState({
//音频数据
data: responseData.data,
loaded: true,
first_load: false
});
return;
}
Alert.alert("加载失败");
}).catch((e) => {
Alert.alert(e.message);
});
}
render() {
return (
<ScrollView style={{flex: 1}}>
<Nav back={true} __jump={() => this.__jump("switch")}/>
<View>
<View style={styles.content}>
<View style={{
width: width,
flexDirection: "row",
backgroundColor: "#f9f9f9",
height: 50
}}>
<View style={{flex: 1, justifyContent: 'center',}}>
</View>
<View style={{flex: 5}}>
<TextInput style={styles.textInput}
placeholder=" Input your destination..." underlineColorAndroid='transparent'
placeholderTextColor="#959595"
onChangeText={(text) => this.setState({text})}/>
</View>
<View style={{flex: 2}}>
<TouchableHighlight onPress={() => {
this.fetchData()
}} underlayColor="#fff">
<View style={styles.commit_button}>
<Text style={{color: '#fff', textAlign: 'center'}}>Search</Text>
</View>
</TouchableHighlight>
</View>
</View>
</View>
</View>
<View style={{height: 1, backgroundColor: "#c8c8c8", marginLeft: 5, marginRight: 5}}/>
{this.renderAudio()}
</ScrollView>
);
}
renderAudio() {
if (this.state.first_load) {
return (
<View style={{flex: 1, alignItems: 'center', justifyContent: 'center', marginTop: 100}}>
<Image style={{height: 200}} source={tra}/>
</View>
)
} else {
if (this.state.loaded) {
const list = []
const data = this.state.data;
for (let i in data) {
let paused = true;
if (!data[i].paused) {
paused = false;
}
let text = (
<View key={i}>
<View style={{flexDirection: 'row', marginTop: 10, marginLeft: 10}}>
<View style={{flex: 9, flexDirection: 'row'}}>
<View style={{
alignItems: 'center',
justifyContent: 'center'
}}>
<Text style={{color: "#646464"}}>{data[i].destination}</Text>
</View>
<View style={{flex: 1, flexDirection: 'column', marginLeft: 10}}>
<View style={{flex: 1}}>
<Text>{data[i].original}</Text>
</View>
<View style={{flex: 1}}>
<Text>{data[i].translate}</Text>
</View>
</View>
</View>
// 播放按钮,点击播放并暂停其他播放中的音频
<TouchableOpacity style={{flex: 1, height: 30, width: 30}} onPress={() => {
let p = this.state.data;
let paused = p[i].paused;
for(let j = 0,len=p.length; j < len; j++) {
p[j].paused = true
}
p[i].paused = !paused;
this.setState({
data: p,
})
}}>
<View>
<Image style={{height: 30, width: 30}}
source={this.state.data[i].paused ? start : starting}></Image>
<Video
source={{uri: data[i].url}}
paused={this.state.data[i].paused}
repeat={true}
//播放结束停止重复播放
onEnd={()=>{
let p = this.state.data;
p[i].paused = true;
this.setState({
data: p,
})
}}
/>
</View>
</TouchableOpacity>
</View>
<View style={{height: 1, backgroundColor: "#939393", marginTop: 10}}/>
</View>
);
list.push(text);
}
return (
<View>
{list}
</View>
)
} else {
return (
<View style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#000'
}}>
<Text>Loading...</Text>
</View>
);
}
}
}
}
var styles = StyleSheet.create({
content: {
alignItems: 'center',
justifyContent: 'center',
flexDirection: "column",
},
bottomButton: {
flexDirection: "column",
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
textInput: {
marginLeft: 10,
marginTop: 10,
height: 32,
backgroundColor: '#fff',
borderWidth: 1,
borderColor: '#e1e1e1',
borderRadius: 8,
fontSize: 10
},
commit_button: {
marginTop: 10,
width: 60,
height: 32,
backgroundColor: '#26c474',
borderRadius: 10,
justifyContent: 'center',
marginLeft: 7
},
service: {
// height: Platform.OS == 'ios' ? iosHeight - 50 : androidHeight - 50,
flexDirection: "column",
backgroundColor: "#fff",
flex: 13,
width: width,
},
box: {
alignItems: 'center',
justifyContent: 'center',
flex: 1,
flexDirection: "column"
}
});
效果图
问题集锦
- 如果xcode提示缺少库libRCTVideo.a
在xcode打开ios源码,将node_modules里的react-native-video/ios里面的.xcodeproj文件导入到Libraries