How to resolve react-video-js-player failing to load media - reactjs

Hello I am trying to use the react video js player but I am getting the error below:
The media could not be loaded, either because the server or network failed or because the format is not supported.
At first, I thought maybe it was the video type because Initially it was a .mkvi video I then changed to mp4 and still nothing I get the same error can I please get help
Code Below: VideoList.js
import React from 'react';
import VideoPlayer from 'react-video-js-player';
const VideoList = (props) =>{
let videos = props.listVideos
return(
<div>
{videos.map(video =>{
return(
<div key={video.id}>
<h3>{video.lecturer}</h3>
<VideoPlayer src={video.video} width="720" height="420" playbackRates={[0.5, 1, 3.85, 16]}/>
</div>
)
})}
</div>
)
}
export default VideoList

Like I said on my comments, typically this error will occur if the video is not existing, has issues with the encoding, file extension, etc. See this example I've written.
In the end, I was correct and the video.video object was returning a relative path instead of an absolute path which resulted in an incorrect link.
Regarding the OP's current solution for this issue, this is not an ideal architecture because it will probably fail when you deploy to production, switch domains, or even just switch ports. Concantenating your base url is fine (e.g., http://127.0.0.1:8000/) but I would have this variable as a single source of truth probably residing at a state at the topmost component or as an environment variable so that anytime you change domains, ports, or IP you can simply change this variable and you won't have to go through all of your components 1 by 1.
Example implementation on Class based components:
Parent component:
state = {
base_url: `http://127.0.0.1:8000/api/`, // local dev api
// base_url: `https://production-server:80/api/` // live site api
// or an environment variable as described on my answer
}
Child component:
<VideoPlayer src={`${this.props.base_url}${content.video}`}

So I managed to find the problem behind this, so I was getting data from the API but when I tried to access the video the API was not giving the full URL that is:
http://127.0.0.1:8000/media/lectures/<here_the_name_of_the_lecture_video>
But the API was giving me a relative path media/lectures/<here_the_name_of_the_lecture_video>
So I had to give the remaining the URL that which the API does not give when I render in the video i.e I had to write the following
<VideoPlayer src={`http://127.0.0.1:8000/api${content.video}`}
So I am wondering
Currently, this solution works but is this solution technically good? Because I am to believe that the API should be giving everything that I need I just have to make requests.
Can you please assist me to come up with a more technically viable solution for this problem

Related

React, nested component with external component

I'm creating a documentation in React for an internal project. To help users to enter the good informations, I ask them some informations in beginning of the documentation such as their username or their machine's IP and save them in a cookie (we have no backend). These datas are display in the documentation to help them to configure their environment.
We also include some codes, command lines and configuration in yaml. To make the code more clear, I use React Syntax Highlighter. It works well except for on things and I don't find a work around: Sometime, the code include the Username or IP. But when I include the components to display these datas in the code, it's not display correctly.
Example:
const config_data = '# Maintainer\n\
MAINTAINER "' + <DisplayName /> + '"\n\n\
# copy your file\n\
COPY ./test.test /usr/local/test.test';
class Test extends React.Component {
render() {
return(
<div>
<SyntaxHighlighter language="dockerfile">
{config_data}
</SyntaxHighlighter>
</div>);
}
}
The result will give me:
# Maintainer
MAINTAINER "[object Object]"
# copy your file
COPY ./test.test /usr/local/test.test
I find this issue which helped me to understand what happens but because the React Syntax Highlighter component is not mine, I can not (not in my knowledge at least) modify it. I also tried to get the data directly from the cookies to display the data directly but the result is the same.
I don't know if it's a bug of the component, if I can render my own component before to include it or if I missed something.
You can use ReactDOMServer to convert the component into a string/markup.
import * as ReactDOMServer from 'react-dom/server';
const config_data = `# Maintainer\n\
MAINTAINER ${ReactDOMServer.renderToStaticMarkup(<DisplayName />)} \n\n\
# copy your file\n\
COPY ./test.test /usr/local/test.test`;

React / Context API / TypeScript : How to init web app and avoid UI flickering at statup?

When a user navigate to my site, I need to initialize the React web app as follow:
If the incoming user has never requested the web app, I want to set the UI language to browser default (navigator.language).
If the incoming user has already visited the site and chosen a prefered language (lang stored in the localStorage), I want to init the UI with this language.
If the incoming user has an account and is already connected (token available in localStorage), I want to auto-connect him and render the app accordingly : login button transformed into a welcome message, UI language set to user preference.
To do so, I'm using React Context API and a defaultUser object.
defaultUser: init a default user
const defaultUser = {
language: 'en_EN',
isConnected: false
}
Context: create a default context
export const AppContext = createContext({
connectedUser: defaultUser,
})
Provider: create the provider with default context
export function AppProvider({ children }: any) {
[...]
const provider = {
connectedUser
}
return (
<AppContext.Provider value={provider}>
{children}
</AppContext.Provider>
)
}
App: init the provider during app start up
export class App extends Component {
static contextType = AppContext
render() {
return (
<AppProvider>
<AppContainer />
</AppProvider>
)
}
}
AppContainer: render the app
export class AppContainer extends Component {
static contextType = AppContext
componentDidMount() {
/** If user is not connected, verify if a stored session exists and use it to connect user */
if (!this.context.connectedUser.isConnected) {
[...do things...]
}
}
The whole mecanism works well except an annoying thing : the web app is systematically initialized with default user values, until the AppContainer::componentDidMount() do the real init job.
This is causing a sort of flickering effect.
I'm struggeling for 2 days on how to fix that, trying to perform Context init before <AppContainer /> rendering, and I'm stuck.
Any recommandations?
EDIT :
For clarity, I'm adding a diagram. Currently :
React App is rendered at start.
Context is initialized at start with default value.
Context is updated when end is reached.
React App is rendered again when end.
Any layout change during these two steps (UI language, UI modification based on user permissions) are clearly visible to the user and generate a sort of flickering.
I found sort of a solution by simply conditionning <AppContainer/> loading, postponing it to the end of the sequence. However instead of having flickering I have now a lag and other unwanted side effects.
The goal would be to differ all the sequence before React Act is rendered, and after Window is available. Then dynamically create the Context, then render all.
I think the point would be resolved if I could dynamically create the AppContext and pass a variable to createContext() during App constructor() or maybe componentWillMount() (not sure when Window is available), but then TypeScript get into play with types issues and I'm still stuck.
You didn't share the code that initializes the context, but I suspect you put the default value to be either a hardcoded value, or navigator.language and therefore experience the flickering. I'd like to suggest two ways to solve this:
Solution 1
Perhaps instead of having a hardcoded default context you could generate the default context programmatically by accessing localStorage.get('lang') or similar? There is a slight drawback to this solution though: You will be mixing concerns of react and the browser, but I think in this case it's an alternative to consider, because it's very simple and obvious to the reader.
Solution 2
Alternatively, when calling ReactDOM.render you could pass down whatever you need from localStorage as a prop to your application and so you keep the browser related logic separate from the pure React stuff.
I hope this makes sense.
Here's my follow-up after Amit suggestions, in case it can help anyone else.
Init Context with functions
Instead of initializing defaultUser with hard-coded values and update it later, I set directly it with a function returning navigator.lang as suggested. This solved the flickering issue on UI labels.
Init data before RectDOM.render
However I still had flickering on UI components for which I have to get the appropriate state from an API call.
Eg, if the incoming user has a valid session token stored in localStorage, the Login button must be disabled. Before doing so, I need to make sure the session token is valid by an async call to the API. I didn't find a way to have it «awaited» by the Context init which seems to be synchronous.
That's where Amit second suggestion get into play. Instead of struggling finding a solution inside React, I did necessary processing before ReactDOM.render, then passing stuffs as props to <Apps/>.
This works pretty well to get and pass the data...
Except that Context API didn't setSate anymore as soon as any of its data was refering to an object from outside the Context. In other word using function calls is ok to init (probably by val), but reference to external objects breaks setState.
Conclusion
As my project is still in early stage, this gave me the chance to get rid of Context API, do the proper init as required, and code the props/states progagation with basic React.

Dynamically Importing Images Based on a Variable

I have a requirement to select, from a local source, an image based on the value passed back from the REST API I am using. For example:
//Psuedo-call from the API
var imageIdToSelect = response.data.imageId
//Then later in the render()
<img src={ baseUrl + imageIdToSelect } />
I have a solution to this, which is to use require() as that allows me to append the url as such:
<img src={ require(baseUrl + imageIdToSelect) } />
This works fine, however, I am using a Microsoft TSLINT setup that does not allow require() over the prefered import at the top of the file "no-require-imports".
I know I am not meant to let linting tools control my work to the point where I am just blindly following rules. So my question is two-fold:
Why is it frowned upon to use require() in such a way. One reason I could think of is that if all of the external files/resources are declared at the top of the file, then you don't have to look through the source to find them hidden in functions.
What would the import x from './' solution look like here? I have seen people creating index.js and index.d.ts files inside their image folders to import and export all the images inside but that seems a tad extraneous.
Edit: I also have just realised that using require() with a non-literal string is a violation of my ts-linting too.
Thanks in advance

Image handling with data input in path

I have an issue with my images in react. When i let the image render like this:
import road from '../../../../assets/images/icons/road.png';
<img src={road} />
It will work but i want it to be dynamic relying on the input of data.
So i tried it this way (where icon is refering to a data set resulting in road):
import road from '../../../../assets/images/icons/road.png';
...
render() {
const { place, date, icon, progress } = this.props.stage;
...
<img src={icon} />
So my guess is that there is an issue with referencing here. From my question you can understand that i am absolutely new to react. What i also noticed is that with the method above i will get an unused var error if i dont load this image. So for example i have a couple of these icons but depending on the data in the dataset it will only render a few. Which i find kind of messy.
I hope you can steer me towards the right direction. Kinda frustrating not being able to implement an image...
With this: Load images based on dynamic path in ReactJs
posted from Subham Khatri i was able to get the answer i desired.
<img src={require(`../../../../assets/images/icons/${icon}.png)`} />
As I understand you are trying to pass the image from this.props.stage. Did you first try console.log(icon). what do you see in the console window. First we need to know whether the data is being passed from props.

Violation 'requestIdleCallbackHandler ' took ms

I'm writing an app generated with create-react-app with redux, react-redux, and react-router. Whenever I click a Link like this:
import React from 'react'
import { Link } from 'react-router'
import ThingCard from '../../components/ThingCard'
const ThingsList = ({things}) => {
return (
<ul>
{things.map(thing =>
<Link to={"/things/"+thing.id} key={thing.id}><ThingCard thing={thing}/></Link>
)}
</ul>
)
}
export default ThingsList
I see the following warnings in my console. I have no idea where they come from or what they mean. Google search didn't yield any useful results. Can these warnings be safely ignored, if not how can I find out more about them? I believe this issue is preventing the parent page from rendering it's children.
I've disabled all network requests.
EDIT: This error only shows up in Chrome Canary and not Google Chrome. However, Google Chrome is not rendering the children properly (potentially due to this issue)
It can be safely ignored. Here is good explanation why do you see this.
The reason you see requestIdleCallback here is most probably because you are using React 16+ which has a totally new architecture Fiber You can read more about it
TL;DR; It just notifies you that some of your/their code took longer than 16ms, thus you may not always get 60fp.

Resources