使用react-native-video实现页面多音频文件播放(ios平台)

最近帮朋友做一下小的app,其中一个功能有以下要求

  • 根据搜索结果返回音频列表
  • 音频播放完毕自动停止
  • 播放一个音频的时候,暂停其他播放中的音频

react-native-video模块安装教程

react-native-video项目地址

  • 安装模块
npm install --save react-native-video
  • 链接ios library
react-native link react-native-video
  • 修改AppDelegate.m
#import "AppDelegate.h"

#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
//导入AVFoundation
#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"
    }
});
效果图

效果图

问题集锦

  1. 如果xcode提示缺少库libRCTVideo.a
    在xcode打开ios源码,将node_modules里的react-native-video/ios里面的.xcodeproj文件导入到Libraries
    这里写图片描述

这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Alex-Leung

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值