react-flv-player浏览器播放内存占用过高的解决办法

1 篇文章 0 订阅

使用react-flv-player播放flv内存占用过高解决办法

最近有React项目,需要播放视频,使用video.js播放HLS说延迟太高,换成rtmp也有延迟,而且依赖Flash,这玩意儿马上被淘汰了。还好可以使用flv.js播放,目前很多直播流也是用的flv,高清,没什么延迟,还跨平台,也很快,那必须用起来啊。
首先下载安装 react-flv-player,我试过npm装不上,只能用cnpm装上。

cnpm i react-flv-player -S

然后引入代码

import {ReactFlvPlayer} from 'react-flv-player';

    render() {
        return (
            <div className={"flv-video-player-wrap"}>
                {
                    this.state.src && <ReactFlvPlayer
                        //url = "http://110.185.101.229:18098/yahz/stream_1.flv"
                        url={this.state.src}
                        heigh="100%"
                        width="100%"
                        hasAudio={false}
                        enableStashBuffer={false}
                        isMuted={false}
                    />
                }
            </div>
        );
    }

这样播放没问题,但是fetch请求会一直拉取数据流,几十分钟后就会让浏览器内存暴涨。使用最简单的方式是做个定时器,10分钟刷新整个页面。但是这样子太low了,现在都什么年代了,还刷新浏览器,都是局部刷新好吧。

在这里插入图片描述
研究下源码也挺简单的,flv提供了destroy方法,销毁再创建,内存就不会一直累加了。修改ReactFlvPlayer.js的源码放上来:

'use strict';

Object.defineProperty(exports, "__esModule", {
    value: true
});

var _createClass = function () {
    function defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ("value" in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }

    return function (Constructor, protoProps, staticProps) {
        if (protoProps) defineProperties(Constructor.prototype, protoProps);
        if (staticProps) defineProperties(Constructor, staticProps);
        return Constructor;
    };
}();

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _flv = require('./flv.min');

var _flv2 = _interopRequireDefault(_flv);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {default: obj};
}

function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}

function _possibleConstructorReturn(self, call) {
    if (!self) {
        throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
    }
    return call && (typeof call === "object" || typeof call === "function") ? call : self;
}

function _inherits(subClass, superClass) {
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }
    subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
            value: subClass,
            enumerable: false,
            writable: true,
            configurable: true
        }
    });
    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}

var ReactFlvPlayer = function (_Component) {
    _inherits(ReactFlvPlayer, _Component);

    function ReactFlvPlayer(props) {
        _classCallCheck(this, ReactFlvPlayer);

        var _this = _possibleConstructorReturn(this, (ReactFlvPlayer.__proto__ || Object.getPrototypeOf(ReactFlvPlayer)).call(this, props));

        _this.myRef = _react2.default.createRef();
        _this.flvPlayerRef = function (element) {
            _this.flvPlayerRef = element;
        };
        return _this;
    }

    _createClass(ReactFlvPlayer, [{
        key: 'componentDidMount',
        value: function componentDidMount() {
            var _props = this.props,
                type = _props.type,
                url = _props.url,
                isLive = _props.isLive,
                enableStashBuffer = _props.enableStashBuffer,
                stashInitialSize = _props.stashInitialSize,
                hasAudio = _props.hasAudio,
                hasVideo = _props.hasVideo,
                handleError = _props.handleError,
                enableWarning = _props.enableWarning,
                enableError = _props.enableError;

            // 组件挂载后,拿到Ref进行操作
            var flvPlayer;
            const $this = this;
            function load_play() {
                if (_flv2.default.isSupported()) {
                    flvPlayer = _flv2.default.createPlayer({
                        type: type,
                        isLive: isLive,
                        url: url,
                        hasAudio: hasAudio,
                        hasVideo: hasVideo
                    }, {
                        enableStashBuffer: enableStashBuffer,
                        stashInitialSize: stashInitialSize
                    });

                    _flv2.default.LoggingControl.enableError = false;
                    _flv2.default.LoggingControl.enableWarn = enableWarning;

                    flvPlayer.attachMediaElement($this.myRef.current); // 将这个DOM付给第三方库
                    flvPlayer.load();
                    flvPlayer.play();
                    flvPlayer.on('error', function (err) {
                        // console.log(err);
                        handleError(err);
                    });
                }
            }

            load_play();
            //2分钟后销毁,再创建,避免浏览器内存过高
            setInterval(function () {
                flv_destroy();
                load_play();
            }, 120000);

            function flv_destroy() {
                flvPlayer.detachMediaElement();
                flvPlayer.destroy();
                flvPlayer = null;
            }
        }
    }, {
        key: 'render',
        value: function render() {
            var _props2 = this.props,
                height = _props2.height,
                width = _props2.width,
                isMuted = _props2.isMuted;

            return _react2.default.createElement(
                'div',
                null,
                _react2.default.createElement('video', {
                    controls: true,
                    muted: {isMuted: isMuted},
                    ref: this.myRef,
                    style: {height: height, width: width}
                })
            );
        }
    }]);

    return ReactFlvPlayer;
}(_react.Component);

ReactFlvPlayer.propTypes = {
    type: _propTypes2.default.string,
    url: _propTypes2.default.string.isRequired,
    isLive: _propTypes2.default.bool,
    hasAudio: _propTypes2.default.bool,
    hasVideo: _propTypes2.default.bool,
    enableStashBuffer: _propTypes2.default.bool,
    stashInitialSize: _propTypes2.default.number,
    height: _propTypes2.default.string,
    width: _propTypes2.default.string,
    isMuted: _propTypes2.default.bool,
    enableWarning: _propTypes2.default.bool,
    enableError: _propTypes2.default.bool,
    handleError: _propTypes2.default.func
};

ReactFlvPlayer.defaultProps = {
    type: 'flv',
    isLive: true,
    hasAudio: true,
    hasVideo: true,
    enableStashBuffer: true,
    stashInitialSize: 128,
    height: '100%',
    width: '100%',
    isMuted: false,
    handleError: function handleError(err) {
        console.log(err);
    },
    enableWarning: false,
    enableError: false
};

exports.default = ReactFlvPlayer;

主要在_createClass方法里,修改了2分钟后销毁,再创建视频的定时器。这样内存就不会太高了,页面上视频会转一下圈,还能接受吧,比刷新整个页面好。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值