【问题标题】:Looping on an interval of audio element with scalajs-react使用 scalajs-react 在音频元素的间隔上循环
【发布时间】:2016-10-27 23:17:43
【问题描述】:

我想构建一个包含audio 元素的小组件,它能够在间隔上循环。区间的两端将被定义为组件的属性。由于timeUpdate 事件没有必要的精度(我希望至少保证 33Hz),我决定使用带有TimerSupport 的后端,并在通过结束后将currentTime 设置回起点间隔。

val AudioRef = Ref[Audio]("audio")
class PlayerBackend extends TimerSupport
val AudioPlayer = ReactComponentB[String]("AudioPlayer")
  .initialState(0L)
    .backend(i => new PlayerBackend())
  .render_P(url => {
    <.audio(
       ^.ref := AudioRef,
      ^.autoPlay  := true,
      ^.controls  := true,
      <.source(^.src := "http://www.stephaniequinn.com/Music/Allegro%20from%20Duet%20in%20C%20Major.mp3"),
      "Your browser does not support the audio element."
    )
  })
  .componentDidMount({ c =>
    c.backend.setInterval(Callback.log({
      if (AudioRef(c).isDefined) ({
        AudioRef(c).get.currentTime
      }) else "nothing"
    }), 1000 millisecond)
  }).configure(TimerSupport.install)
  .build

这个小例子我只想打印播放器的当前位置,但出于某种原因(回调在组件挂载时关闭了后端上下文的副本?)AudioRef(c) 指向一个旧版本的音频元素。知道如何解决这个问题吗?我对其他设计也很感兴趣,因为我对 ScalaJS 和 React 都没有真正的经验。

【问题讨论】:

    标签: scala audio reactjs scala.js scalajs-react


    【解决方案1】:

    问题在于 log 调用仅对其参数进行一次评估,从而产生一个值,然后一遍又一遍地记录。正确的代码应该是这样的:

    .componentDidMount({ c =>
      c.backend.setInterval(CallbackTo[Double] {
        if (AudioRef(c).isDefined) ({
          AudioRef(c).get.currentTime
        }) else 0
      } >>= Callback.log, 1000 millisecond)
    })
    

    它创建一个回调来提取currentTime 值(或什么都没有),然后将平面映射到另一个记录该值的回调。

    【讨论】:

      【解决方案2】:

      我最终通过在Callback 中获取基于其id 的音频元素来设置currentTime 属性,因此我的解决方案目前如下所示:

      class PlayerBackend($: BackendScope[String, Unit]) extends TimerSupport
      val AudioPlayer = ReactComponentB[String]("AudioPlayer")
        .initialState(())
          .backend(i => new PlayerBackend(i))
        .render_P(url => {
          <.audio(
            ^.id := "audio",
            ^.autoPlay  := true,
            ^.controls  := true,
            <.source(^.src := "http://www.stephaniequinn.com/Music/Allegro%20from%20Duet%20in%20C%20Major.mp3"),
            "Your browser does not support the audio element."
          )
        })
        .componentDidMount({ c =>
          c.backend.setInterval(
            Callback({document.getElementById("audio").asInstanceOf[Audio].currentTime = 5.0}) ,
            1 seconds
          )
      })
      .configure(TimerSupport.install)
      .build
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-11-26
        • 1970-01-01
        • 2018-07-14
        • 1970-01-01
        • 2019-02-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多