rrweb实现用户实时轨迹录播

627 阅读2分钟

使用说明(readme.md

网页用户轨迹记录和播放(可做网页直播)

使用时依赖两个包npm install --save rrweb rrweb-player 当前sdk依赖两个包,录入依赖rrweb,回放或者实时播放依赖

录制

    import WebRecord from '~path/WebTrackSdk/WebRecord'
    
    const recordInstall = new WebRecord({
      emit(event: any) {
      // 以下为本地做的一个storage监听,做本地网页storage监听达到监听数据实时查看效果,可以切换为
        localStorage.setItem('rrweb', JSON.stringify(event))
      // 以上为本地做的一个storage监听,做本地网页storage监听达到监听数据实时查看效果
      },
    })


    recordInstall.start() //开始录了
    // recordInstall.stop() //结束录制

实时播放

    import 'rrweb-player/dist/style.css' // 使用回放功能需要单独引入其对于css
    import WebPlayer from '~path/WebTrackSdk/WebPlayer'
    
    const ele = document.getElementById('player')
    if (ele) {
      let player = new WebPlayer({
        target: ele,
        liveMode: true,
        events: [],
      })
      // 以下为本地做的一个storage监听,做本地网页storage监听达到监听数据实时查看效果
      window.addEventListener('storage', function (e) {
        if (e?.key === 'rrweb' && e?.newValue) {
          const eventItem = JSON.parse(e?.newValue)
          player?.addEvent(eventItem)
        }
      })
      // 以上为本地做的一个storage监听,做本地网页storage监听达到监听数据实时查看效果
    }

网页操作轨迹回放

    import 'rrweb-player/dist/style.css' // 使用回放功能需要单独引入其对于css
    import WebPlayer from '~path/WebTrackSdk/WebPlayer'
    let userTrackData = [event,...]//此处为用户轨迹数据,一次性从结口获取
    const ele = document.getElementById('player')
    if (ele) {
      let player = new WebPlayer({
        target: ele,
        events: userTrackData,
      })
      // 以下为本地做的一个storage监听,做本地网页storage监听达到监听数据实时查看效果
      window.addEventListener('storage', function (e) {
        if (e?.key === 'rrweb' && e?.newValue) {
          const eventItem = JSON.parse(e?.newValue)
          player?.addEvent(eventItem) // 也可以按阶段接口获取,以免回放数据过大的时候可以用此方式
        }
      })
      player?.start()  // 开始回放
      // player?.stop()  // 结束回放
      // 以上为本地做的一个storage监听,做本地网页storage监听达到监听数据实时查看效果
    }

录入脚本(~path/WebTrackSdk/WebRecord)

import { record } from 'rrweb'
export interface WebRecordProps {
  state?: 'start' | 'stop'
  emit?: Function //参数1实时传递录入数据,参数2为开始到现在的所有数据
}
class WebRecord {
  events?: any[]
  record?: any
  emit?: Function
  private _state: 'stop' | 'start'
  set state(state: 'stop' | 'start') {
    this._state = state === 'start' ? 'start' : 'stop'
  }
  get state() {
    return this._state
  }
  constructor(params?: WebRecordProps) {
    this.state = params?.state || 'stop'
    this._state = params?.state || 'stop'
    this.emit = params?.emit
    if (this.state === 'start') {
      this.start()
    }
  }
  // 开始录制
  start() {
    this.state = 'start'
    this.events = []
    const vm = this
    this.record = record({
      emit(event) {
        if (vm.state === 'start') {
          vm.events = vm.events || []
          // 将 event 存入 events 数组中
          vm.events.push(event)
          vm.emit && vm.emit(event, vm.events || [])
        }
      },
      recordCanvas: true,
    })
    return this
  }
  // 结束录制
  stop() {
    this.state = 'stop'
    return this
  }
  getEvents() {
    return this.events || []
  }
}

export default WebRecord

播放脚本(~path/WebTrackSdk/WebPlayer)

import rrwebPlayer from 'rrweb-player'

export interface WeRePlayerProps {
  target: HTMLElement
  liveMode?: boolean //是否为实时转播模式
  autoPlay?: boolean
    events?: any[]
    speed?: number
    }
class WeRePlayer {
  private _events: any[]
  rePlayer: any
  target: HTMLElement
  speed: number
  liveMode?: boolean //是否为实时转播模式
  autoPlay?: boolean
  constructor(props: WeRePlayerProps) {
    this.events = props?.events || []
    this._events = props?.events || []
    this.target = props.target
    this.speed = props?.speed || 1
    this.liveMode = !!props?.liveMode
    this.autoPlay = !!props?.autoPlay
  }
  set events(events: any[]) {
    this._events = events || []
    if (this?._events?.length > 2 && !this.rePlayer) {
      this.rePlayer = new rrwebPlayer({
        target: this.target,
        props: {
          liveMode: this.liveMode,
          autoPlay: this.liveMode ? undefined : this.autoPlay,
          showController: !this.liveMode,
          speed: this.speed || 1,
          UNSAFE_replayCanvas: true,
          events: this.events || [],
        },
      })
    }
  }
  get events() {
    return this._events
  }
  //   开始
  start() {
    if (!this.liveMode) {
      this?.rePlayer?.play()
    }
  }
  //   暂停
  stop() {
    if (!this.liveMode) {
      this?.rePlayer?.pause()
    }
  }
  goto(timeOffset: number, play?: boolean) {
    if (!this.liveMode) {
      this?.rePlayer?.goto(timeOffset, play)
    }
  }
  //设置速度
  setSpeed(speed: number) {
    if (!this.liveMode) {
      this.speed = speed
      this?.rePlayer?.setSpeed(speed || 1)
    }
  }
  addEvent(event: Object) {
    this.events = [...(this.events || []), event]
    this?.rePlayer?.addEvent(event)
  }
}

export default WeRePlayer

文献

详细使用地址[rrweb]

github[rrweb-io]