Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't seek through video from Rails Active Storage with Rails-Webpacker React Frontend

Okay so I'm having an issue with seeking through videos in my react components with Rails Webpacker. I can make them play but I can't seek through them.

I'm using Rails Active Storage to upload the videos then sending their urls to my react component via an html attribute rendered by rails_blob_path(@post.video) (see below snippet on step 9). In my react component I have a <video /> element with the source being that parsed attribute. From there I have methods that control the element via a React.createRef(). One of the methods (play()) works as expected. However, my seek() method does not and I don't understand why.

I made a minified example (repo) to isolate the problem and here are the following steps I took:

  1. rails new [app] --webpacker=react
  2. cd into [app], rails active_storage:install
  3. rails g scaffold post title:string
  4. rails db:migrate
  5. add line has_one_attached :video to app/models/post.rb
  6. add :video to white-listed params in app/controllers/posts_controller.rb
  7. add below snippet as a form field in app/views/posts/_form.html.erb

<div class="field">
  <%= form.label :video %>
  <%= form.file_field :video %>
</div>
  1. add below to app/views/posts/show.html.erb

<div id='payload' url='<%= rails_blob_path(@post.video).to_json %>'></div>
<div id='hello-react'></div>
<%= javascript_pack_tag 'hello_react' %>
  1. change app/javascript/packs/hello_react.jsx to have:

import React from 'react'
import ReactDOM from 'react-dom'

const node = document.getElementById('payload')
const url = JSON.parse(node.getAttribute('url'))

class App extends React.Component {

  componentWillMount() {
    this.videoRef = React.createRef()
  }

  seek = (seekTo = 0) => {
    this.videoRef.current.currentTime = seekTo
  }

  play = () => {
    this.videoRef.current.play()
  }

  render() {
    return (
      <div>
        <video ref={this.videoRef} controls>
          <source src={url} type='video/mp4' />
        </video>
        <button onClick={ (e) => {this.seek(5)} }>+5</button>
        <button onClick={ (e) => {this.play()} }>Play</button>
      </div>
    )
  }
}

ReactDOM.render(
  <App />,
  document.getElementById('hello-react')
)
  1. start the server with rails s, go to localhost:3000/posts/new
  2. create a post (you'll need a video to upload), you'll be redirected on submitting to the hello-react pack.

I've posted this before but have not gotten an answer. This is the first time I've made a separate project and outline of the steps to isolate the issue. Hopefully that relays how desperate I am. Please let me know if I need to explain any steps or if you all need anymore info. Thank you all in advance for your help.

Edit 11/11/18: One answer has pointed out that it is a browser issue. I was using Chrome for all my testing but when I used FireFox it worked as expected. Still not sure how to fix this so that the app works cross-browser.

like image 304
Gregory Jaros Avatar asked Oct 29 '18 20:10

Gregory Jaros


1 Answers

I have tried your code.And I assume that you test your application in Chrome.It maybe not working in Chrome.There are some setting in Chrome server that made it can't work out with currentTime.

So I recommend that you try it with another browser,like firefox.And if you usually want to use it in Chrome,set the application online and set the src of the full url of the video.

BTW,is the +5 button should be += not =?

this.videoRef.current.currentTime += seekTo 

this.videoRef.current.currentTime = seekTo

About the full url,now the url setting for video is something like this:"/rails/active_storage/disk/.../test.mp4"

<source src={url} type='video/mp4' />

You can change the url to an example to check it.

<source src={"https://video.pc6.com/v/1807/bdsphcsp.mp4"} type='video/mp4' />

The src here is just an example,which begin with http or https and end with mp4·

About the full url and http/https

This problem is a little complicated to explain.There are many ways, but I am familiar with nginx and puma.So I give a process based on them.

1.You need a online server with has a pulic network IP.

2.You need a domain name;

3.add puma to rails project, clone the project to online server and run it with "bundle exec -C config/puma.rb -d"

  1. deploy nginx and configure domain name、port 、host record and other things in nginx

  2. add url to your "url" in hello-react.jsx,like this:

    src={"https://...."+ url}

like image 174
Root Avatar answered Nov 20 '22 19:11

Root