I want to include an audio player that plays a wav file that is loaded from a URL in a React component. Although this should work straight forward with the HTML5 <audio> element, I cannot get it to play (I just see the control elements).
I tried to play a .mp3 with the same code, which works. I checked in Chrome and Safari which are supposed to support .wav - it works in neither of them. I tried to replace the <audio> element with a react-audio-player, a react-player and a react-sound element - none of them works.
When I open the URL, the sound is downloaded as an attachment.
render() {
const wavUrl = config.fileServer+this.props.values.id+".wav";
return (
<audio controls>
<source src={wavUrl} type="audio/wav" />
Your browser does not support the audio element.
</audio>
);
}
I expect to see an audio controller that starts playing the sound when I press play. Instead, I see an audio controller that does nothing when I press play, and that claims that the audio file is 0 seconds long. I checked the URL - it is correct if I past it as URL in my browser directly.
If you are using create-react-app you have to import the audio file.
import wavUrl from './path/to/file';
// ... rest of code here
As mentioned Kitanga, you can use import to load files from public (instead of full URL access), example:
import somefile from '../public/assets/mp3/test1.mp3'
then
Play extends Component {
...
}
render(
<Play file=somefile>
)
But if you found webpack error message at start: "You may need an appropriate loader to handle this file type..." then seems you need to load appropriate extension npm package to read it and configure webpack.config.js, example:
...
module: {
rules: [
{
test: /\.mp3$/,
loader: "file-loader"
},
...
]
...
...
if "file-loader" not installed then use example:
npm install --save file-loader
Related
I have a little problem in my application.
I use i18next and react-i18next for the translation and have already included it.
The whole translation comes from 1 file for each language and that is a mess with over 4000 rows :(
Now I want update this so that i18next would take the translation files placed in the different component-folders and their children-folders.
The folder-structure should look like this after the update:
scr
- components
-- Header
---translations (en/translation.json, de/translation.json)
-- Dashboard
--- translations (en/translation.json, de/translation.json)
--- Menu
---- translations (en/translation.json, de/translation.json)
---- ExampleComponent.tsx
---- ...
--- Cards
---- translations (en/translation.json, de/translation.json)
...
I already figured out how I can handle the automatic export via babel and babel-i18next-plugin with the "namespace"
So, my code (example Menu) would be written like this:
const { t } = useTranslation("Dashboard/Menu")
const explString = t("ExampleComponent.ExampleString","This is an example")
In babel I placed the plugin like this:
[i18next-plugin, {"outputPath": "src/components/{{ns}}/translations/{{locale}}/translation.json"}]
This runs without problems. It takes the namespace as a folder-structure and places the translation-files into the translation-folder including the correct keys.
Now, how I can tell i18next, where to find the translation-files?
I could only figure out that I can import the files (file-by-file) inside a resource.
I tried backend plugins (html-backend, async-storage-backend, local-storage-backend and filesystem) with
backend: { loadPath: "components/{{ns}}/translations/{{lng}}/translation.json" }
(The i18next.ts is placed inside src/)
and I get the warnings that the keys aren't found.
Also, you can see that I use TypeScript.
In my webpack I tried it with the ts-i18next-loader with this inside the webpack configuration file:
{
test: /\translation.json$/,
exclude: /node_modules/,
loader: 'i18next-ts-loader',
options: {
localeFilesPattern: 'src/components/{{ns}}/translations/{{lng}}/translation.json',
},
},
If I only had 5-6 translation-files for each language / namespace it would not be a problem to put it inside the resource but at the end I have more than 100 files for each language.
Would be nice if anyone had a solution to my problem. If you need any further information I can update the post.
Cheers
There's an alternative plugin to be used, suggested in the official documentation: https://www.i18next.com/how-to/add-or-load-translations#lazy-load-in-memory-translations
i18next-resources-to-backend helps to transform resources to an i18next backend. This means, you can also lazy load translations, for example when using webpack:
import i18next from 'i18next';
import resourcesToBackend from 'i18next-resources-to-backend';
i18next
.use(resourcesToBackend((language, namespace, callback) => {
import(`./locales/${language}/${namespace}.json`)
.then((resources) => {
callback(null, resources)
})
.catch((error) => {
callback(error, null)
})
}))
.init({ /* other options */ })
Found the solution.
After i included the "webpack backend for i18next" it solved the problem and the translation gets the correct file.
i18next webpack backend by SimeonC
I am attempting to use a map function to build a carousel from an array of objects. One of the objects is the image source. For some reason, using require to specify the img src no longer works. Here is a code snippet that shows the problem.
import myImg from '../images/myImg.jpg';
....
<img src={myImg} alt="This message is not expected to show"></img>
<img src="../images/myImg.jpg" alt="This message is expected to show"></img>
<img src={require("../images/myImg.jpg")} alt="Fails when message shows"></img>
The result is:
the 1st image displays without an alt message (this is expected)
the 2nd image does not display. The displayed alt message is: "This message is expected to show"
the 3rd image does not display. The displayed alt message is: "Fails when message shows"
I suspect there is something wrong in my wordpack.config settings. I am using file-loader. The code snippet for this is:
loaders: [
{
test: /.s?css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
],
}
],
Is file-loader the wrong choice? Are my settings wrong? I tried this without file-loader and got the same results. This is strange because specifying the file src for an img using require used to work several months ago.
The answer is to use require('pathname').default versus require('pathname'). File-loader and webpack are not required.
Require returns a module vs the uri. One of the methods for require is default.
I discovered this by
console.log(require("./images/img.jpg"));
This returns a module versus the uri. Opening the module in console showed the available methods.
I then tried
console.log(require("./images/img.jpg").default);
This returns the same uri to the static image as import.
The obvious advantage of using require vs. import is that require is performed dynamically. The supplied path can come from an array or object. For example
var img = ["img0.jpg", "img1,jpg", "img2.jpg" ];
var i = 1;
<img src={require(./images/${i}).default} alt="some message"/>
I am testing Jimp.js for image manipulation (using React with react-scripts, npm: 6.14.4, node: v12.16.3)
Everything is going well except writing text on a loaded image
import Jimp from 'jimp'
Jimp.read(image)
.then(image => {
console.log('image loaded', image)
Jimp.loadFont(Jimp.FONT_SANS_32_WHITE).then(font => {
console.log('font loaded', font)
image.print(font, 10, 10, 'Hello world that wraps!', 12)
// write image
})
})
This throws an error "error parsing font malformed file -- no element" in browser.js of load-bmfont module line 71 and dont execute the log 'font loaded'.
Googling not help i found only 2,3 items about this, associate with using custom fonts - but i use standard font from Jimp. (Using BMFont files instead of Jimp standard fonts doesnt help)
My first thought was the error ocured in a React App in the browser, so i write a Jest test to see if its work without browser context but it fail just like that.
Got any ideas?
Solved...
I'm using the React App within a Java Web Framework in a JSP File.
Jimp.loadFont(Jimp.FONT_SANS_32_WHITE)
search the font in a path that doesn`t exist for the webapp.
Moving the font files to a reachable path with context root
Jimp.loadFont(`${CONTEXT_ROOT}/foo/bar/font.font`) works.
I am trying to load a file from a folder using a name from react props.
when I write this:
import FileImage from '!!file-loader!../public/uploads/file-1589134024728.file';
<img src={FileImage}/>
everything works (but is static). In elements I see:
<img src="368d70b7855164f45e8b1c68db4d549c.file">
[![working][1]][1]
But using this:
src={`!!file-loader!../public/uploads/${file}`}
will show as
<img src="!!file-loader!../public/uploads/file-1589134024728.file">
[![not working][2]][2]
GET http://localhost:8080/public/uploads/file-1589134024728.file 404 (Not Found)
I also tried
src={`../public/uploads/${file}`}
while webpack.config.js looks like that:
{
test: /\.(woff(2)?|ttf|eot|svg|file)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
}```
I believe I somehow need to return [contenthash].[ext] but how?
[1]: https://i.stack.imgur.com/ZDx6l.png
[2]: https://i.stack.imgur.com/lCnMd.png
These files look like they are uploaded, which means you don't have access to their names at build time. This is ok, you have the file name.
You need to make sure that the /uploads/ directory is available through your HTTP server, and then you can use src={'/uploads/' + file} to load the resource from that location.
Even if these are not user uploads, but static files that you provide, then you can put them in your public/uploads directory and still just link them using their location on the webserver. It's hard to be sure without knowing where file comes from.
I have been trying to load images using webpack, but somehow it's not working.
here's the related code
{ test: /\.(jpe?g|png|gif)$/i, loader: 'file-loader?name=[name].[ext]' },
and here's one example of the component where the image should load
<ListItem
leftAvatar={
<Avatar src="assets/images-demo/avatars/128.jpg" />
}
but when the page loads, I get
http://localhost:8080/assets/images-demo/avatars/128.jpg 404 (Not Found)
In the network tab, I see the type of the images as text/html, (not sure why) and I see the initiator as DOMLazyTree. so, could you give me an idea of what's going wrong here?