Comments (25)
The error I'm seeing in the sandbox is different from the previous errors, but it's progress nonetheless. I'm not very familiar with Next.js, so I did some research and I found that Next.js is not natively compatible with ECMAScript module packages. See: vercel/next.js#9607. This is understandable since ES module support (i.e. import
, export
vs. CommonJS require
etc.) is relatively new to NodeJS. The ultimate fix for this will be for Next.js to add support for ES module packages.
There is a work-around though. You can use the next-transpile-modules
to selectively transpile the ES module packages. icecast-metadata-reader
, codec-parser
, and mse-audio-wrapper
are all ES module packages and will need to be transpiled.
Here's the sandbox using the next-transpile-modules
https://codesandbox.io/s/wonderful-firefly-sd9vn?file=/next.config.js
next.config.js
:
const withTM = require("next-transpile-modules")([
"icecast-metadata-player",
"mse-audio-wrapper",
"codec-parser"
]);
module.exports = withTM({
future: {
webpack5: true
}
});
For reference, this is the current error:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /sandbox/node_modules/icecast-metadata-player/src/IcecastMetadataPlayer.js
require() of ES modules is not supported.
require() of /sandbox/node_modules/icecast-metadata-player/src/IcecastMetadataPlayer.js from /sandbox/.next/server/pages/index.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename IcecastMetadataPlayer.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /sandbox/node_modules/icecast-metadata-player/package.json.
at Module._extensions..js (internal/modules/cjs/loader.js:1080:13)
at Object.require.extensions.<computed> [as .js] (/sandbox/node_modules/ts-node/src/index.ts:1045:43)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Module.require (internal/modules/cjs/loader.js:952:19)
at require (internal/modules/cjs/helpers.js:88:18)
at Object.icecast-metadata-player (/sandbox/.next/server/pages/index.js:33:18)
at __webpack_require__ (/sandbox/.next/server/webpack-runtime.js:33:42)
at eval (webpack-internal:///./src/pages/index.tsx:4:81)
at Object../src/pages/index.tsx (/sandbox/.next/server/pages/index.js:22:1)
at __webpack_require__ (/sandbox/.next/server/webpack-runtime.js:33:42)
at __webpack_exec__ (/sandbox/.next/server/pages/index.js:65:52)
at /sandbox/.next/server/pages/index.js:66:28
at Object.<anonymous> (/sandbox/.next/server/pages/index.js:69:3)
at Module._compile (internal/modules/cjs/loader.js:1063:30)
at Module.m._compile (/sandbox/node_modules/ts-node/src/index.ts:1056:23) {
code: 'ERR_REQUIRE_ESM'
}
from icecast-metadata-js.
You can setup your own reverse proxy that will append the CORS headers you want.
You will not be able to pull ICY or Ogg metadata without CORS; however, if real-time metadata isn't important to you, you might take a look at icecast-metadata-stats
which can be set up to poll for metadata from the JSON or XML endpoints.
If it were me, I would set up my own Icecast server on something like an Amazon EC2 or Digital Ocean droplet. You would have full control over the configuration, but you also would accept the risk of missconfiguing something, and having your server vulnerable to security exploits.
from icecast-metadata-js.
I'm pretty sure this is happening because icecast-metadata-player doesn't have a main
entry point in the package.json. Since Next.js does server side rendering, it's looking for a way to bundle the main NodeJS entry point, and it appears to be ignoring the browser entry point. I went ahead and added main
in the package.json in this branch, if you want to pull that down and give that a try: https://github.com/eshaz/icecast-metadata-js/tree/fix-exports
Also, you will need to instantiate the player client side. icecast-metadata-player creates the audio element and accesses a few browser APIs when a new instance is created. I think you could accomplish this by wrapping the instantiation in a useEffect
hook which is what is suggested here: vercel/next.js#17963 (comment)
Let me know if that helps.
from icecast-metadata-js.
Hi
Thanks for your quick reply!
I've tried it, using this process:
- Clone the repo and checkout the branch
fix-exports
. - Link the
icecast-metadata-player
andicecast-metadata-js
packages usingnpm link
in the specific folders in/src
as global npm packages on my machine. - Using the packages inside my project using
npm link icecast-metadata-player
andnpm link icecast-metadata-js
. - Import the player
import IcecastMetadataPlayer from 'icecast-metadata-player';
- Using
new IcecastMetadataPlayer(...)
only in client-side code.
Unfortunately, now Next.js throws errors during the compilation (dev mode):
Error: Debug Failure. False expression.
at getConstructorDefinedThisAssignmentTypes (/path/to/my/project/node_modules/typescript/lib/typescript.js:50877:22)
at getWidenedTypeForAssignmentDeclaration (/path/to/my/project/node_modules/typescript/lib/typescript.js:50713:67)
at getTypeOfVariableOrParameterOrPropertyWorker (/path/to/my/project/node_modules/typescript/lib/typescript.js:51077:24)
at getTypeOfVariableOrParameterOrProperty (/path/to/my/project/node_modules/typescript/lib/typescript.js:51020:28)
at getTypeOfSymbol (/path/to/my/project/node_modules/typescript/lib/typescript.js:51353:24)
at getTypeOfInstantiatedSymbol (/path/to/my/project/node_modules/typescript/lib/typescript.js:51305:44)
at getTypeOfSymbol (/path/to/my/project/node_modules/typescript/lib/typescript.js:51344:24)
at /path/to/my/project/node_modules/typescript/lib/typescript.js:75447:36
at Object.forEach (/path/to/my/project/node_modules/typescript/lib/typescript.js:382:30)
at checkIndexConstraints (/path/to/my/project/node_modules/typescript/lib/typescript.js:75446:20)
at checkClassLikeDeclaration (/path/to/my/project/node_modules/typescript/lib/typescript.js:75769:17)
at checkClassDeclaration (/path/to/my/project/node_modules/typescript/lib/typescript.js:75664:13)
at checkSourceElementWorker (/path/to/my/project/node_modules/typescript/lib/typescript.js:77034:28)
at checkSourceElement (/path/to/my/project/node_modules/typescript/lib/typescript.js:76875:17)
at Object.forEach (/path/to/my/project/node_modules/typescript/lib/typescript.js:382:30)
at checkBlock (/path/to/my/project/node_modules/typescript/lib/typescript.js:74031:20)
Adding type declarations with typescript makes no difference. I've tried it using this:
// NOTE: This is incomplete! I just typed the part of the api that I need.
declare module 'icecast-metadata-player' {
interface MetadataIcy {
StreamTitle: string;
}
interface IcecastMetadataPlayerOptions {
audioElement?: HTMLAudioElement;
enableLogging?: boolean;
retryTimeout?: number;
metadataTypes?: ('icy' | 'ogg')[];
// Callbacks
// Called when metadata is synchronized with the audio.
onMetadata?: (
metadata: MetadataIcy,
timestampOffset: number,
timestamp: number,
) => void;
// Called when the fetch request is started.
onLoad?: () => void;
// Called when fetch request begins to return data.
onStreamStart?: () => void;
// Called when the audio element begins playing.
onPlay?: () => void;
// Called when stream data is sent to the audio element.
onStream?: (streamData: never) => void;
// Called when the fetch request completes.
onStreamEnd?: () => void;
// Called when the stream is completely stopped and all cleanup operations are complete.
onStop?: () => void;
}
class IcecastMetadataPlayer {
static canPlayType(mimeType: string): '' | 'maybe' | 'probably';
constructor(endpoint: string, options?: IcecastMetadataPlayerOptions);
play(): Promise<void>;
stop(): Promise<void>;
detachAudioElement(): void;
audioElement: HTMLAudioElement;
icyMetaInt: number;
state: 'loading' | 'playing' | 'stopping' | 'stopped' | 'retrying';
}
export default IcecastMetadataPlayer;
}
from icecast-metadata-js.
The typescript declarations are a good idea, and having those in this project would be helpful.
Could you try updating your package.json
file to reference the path to the git clone on your computer? I find it easier to import local dependencies this way vs. using npm link
. You should only need to have icecast-metadata-player
as a dependency and not have to do anything with icecast-metadata-js
. Those are actually different NPM packages, even through both of them exist in this repository.
I was able to get the example code you have to compile by following these steps:
- Change
"icecast-metadata-player": "1.2.2",
to"icecast-metadata-player": "file:../icecast-metadata-js/src/icecast-metadata-player"
inpackage.json
where the file path is the relative path from your project to the git clone you have :"dependencies": { "icecast-metadata-player": "file:../icecast-metadata-js/src/icecast-metadata-player", "next": "latest", "react": "^16.13.1", "react-dom": "^16.13.1" },
- Run
npm i
- Run
npm start
from icecast-metadata-js.
Hi @eshaz
Unfortunately, importing it directly, didn't workout. I assume you didn't test it with a typescript Next.js project.
I've created a reproduction repository to showcase the error:
https://github.com/michaelschufi/icecast-metadata-player-test
This is basically Next.js' typescript custom server example.
As you will see it throws the same error as I have posted.
from icecast-metadata-js.
I wasn't able to reproduce the error using your test repo. Everything compiled and ran nicely for me. Nothing played, but there wasn't any code in there that would have started playback. Maybe you need to delete your node_modules
folder or something like that? I don't believe this compilation error is an issue with IcecastMetadataPlayer based on the information we have so far.
I really like the idea of typescript definitions in this project, so I went ahead and expanded upon what you typed up and added those to the fix-exports
branch.
As I was testing out the new type definitions, I also updated your example by using the React hooks to tell Next.js to instantiate IcecastMetadataPlayer client side so you can play back the stream successfully. Feel free to use this in your code base:
src/pages/index.tsx
:
import IcecastMetadataPlayer, {IcyMetadata} from "icecast-metadata-player";
import { NextPage } from "next";
import { useState, useEffect } from "react";
const MyComponent = () => {
const [player, setPlayer] = useState<IcecastMetadataPlayer>() as [IcecastMetadataPlayer, any];
const [metadata, setMetadata] = useState<string>();
useEffect(() => {
setPlayer(new IcecastMetadataPlayer("https://dsmrad.io/stream/isics-all", {
onMetadata: (metadata: IcyMetadata) => {setMetadata(metadata.StreamTitle)}
}))
}, [])
return (
<>
<button onClick={() => player.play()}>Play</button>
<button onClick={() => player.stop()}>Stop</button>
<div>{metadata}</div>
</>
)
};
const Home: NextPage<Record<string, never>> = () => <MyComponent />;
export default Home;
I'm going to put a PR in to track these updates in the fix-exports
branch and I plan on merging and released it within the next few days. I'll leave the PR open for a few days to give you a chance to put in some feedback / comments if you want.
from icecast-metadata-js.
I wasn't able to reproduce the error using your test repo. Everything compiled and ran nicely for me. Nothing played, but there wasn't any code in there that would have started playback. Maybe you need to delete your
node_modules
folder or something like that? I don't believe this compilation error is an issue with IcecastMetadataPlayer based on the information we have so far.
That's really strange. For me the error happens only after I open the page in the browser (error is in the server console). Or when hot reloading (though not in this bare-bones project).
I really like the idea of typescript definitions in this project, so I went ahead and expanded upon what you typed up and added those to the
fix-exports
branch.
That sounds awesome!
As I was testing out the new type definitions, I also updated your example by using the React hooks to tell Next.js to instantiate IcecastMetadataPlayer client side so you can play back the stream successfully. Feel free to use this in your code base:
src/pages/index.tsx
:import IcecastMetadataPlayer, {IcyMetadata} from "icecast-metadata-player"; import { NextPage } from "next"; import { useState, useEffect } from "react"; const MyComponent = () => { const [player, setPlayer] = useState<IcecastMetadataPlayer>() as [IcecastMetadataPlayer, any]; const [metadata, setMetadata] = useState<string>(); useEffect(() => { setPlayer(new IcecastMetadataPlayer("https://dsmrad.io/stream/isics-all", { onMetadata: (metadata: IcyMetadata) => {setMetadata(metadata.StreamTitle)} })) }, []) return ( <> <button onClick={() => player.play()}>Play</button> <button onClick={() => player.stop()}>Stop</button> <div>{metadata}</div> </> ) }; const Home: NextPage<Record<string, never>> = () => <MyComponent />; export default Home;
I'm doing this in the bigger project already. Doesn't seem to be the source of the problem. And it didn't fix it when I updated this code.
I'm going to put a PR in to track these updates in the
fix-exports
branch and I plan on merging and released it within the next few days. I'll leave the PR open for a few days to give you a chance to put in some feedback / comments if you want.
Cool! Looks good at a first glance.
I'm really wondering why you cannot reproduce the error.
Could you maybe release the fix-export
branch with a specific tag to npm? This way, I can try reproducing the error on an online sandbox service.
from icecast-metadata-js.
@michaelschufi I released icecast-metadata-player/1.3.1 with all of the changes in fix-exports
. Merging the PR automatically closed this issue, but if you are still having problems with it please go ahead and reopen this issue.
It's possible that we are using different versions of Node / NPM, or maybe the OS is impacting this in some way? Maybe you have some customization on your environment that I don't?
I'm using:
nvm: 7.7.6
Node: 15.14.0
OS: Linux 5.8.0-53-generic 20.04.1-Ubuntu SMP Thu May 6 09:52:46 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
from icecast-metadata-js.
@eshaz
Sounds good!
Unfortunately, the import doesn't work. I've updated the reproduction repo and it's reproducible on CodeSandbox:
https://codesandbox.io/s/suspicious-yonath-xnbow
from icecast-metadata-js.
Is there any chance the Player will work in Next JS 13? I really need to extract the metadata.
from icecast-metadata-js.
It should work, as long as icecast-metadata-player
is only loaded client side.
from icecast-metadata-js.
Thanks for answering. I'm getting the error in NextJS 13:
Module '"icecast-metadata-player"' has no exported member 'IcecastMetadataPlayer'. Did you mean to use 'import IcecastMetadataPlayer from "icecast-metadata-player"'?ts(2614)
Could you give me an example of how to make it work for the stream: https://servidor18.brlogic.com:7436/live?type=.m3u ?
from icecast-metadata-js.
I don't have any Next JS examples, but you can look at the demo code for plenty of client side examples. If you post a link to your code, I might be able to help, but you should reach out / search within the Next JS community on this as well.
from icecast-metadata-js.
OK thanks. I will try harder for this. I confess that I'm new to Front-End with React and NextJS. I've been able to easily extract metadata in native mobile apps for iOS and Android and with package Just_Audio for Flutter. Thanks for your help.
from icecast-metadata-js.
Trying something similar to the example given above of michaelschufi, I get a warning only when accessing through the browser.
from icecast-metadata-js.
There must be something wrong with your build process. icecast-metadata-js
is supported in Node and browser and it looks like your build is selecting the Node export. You will need to configure your build to use the browser export.
from icecast-metadata-js.
With this code I no longer have the previous errors. Now I am having CORS error. Any suggestion?
from icecast-metadata-js.
Take a look at the readme on CORS and the other git issues tagged CORS.
from icecast-metadata-js.
I gave it a feel in the Readme and added the suggested headers but the error remains. Is there any other configuration to be done in NextJS 13?
from icecast-metadata-js.
happy!
With your example URL it works. It looks like my Stream server doesn't have Cors for all origins.
from icecast-metadata-js.
@oseiasmribeiro the headers should be returned from the icecast server...
Make sure to setup icecast to return the required headers:
https://www.icecast.org/docs/icecast-trunk/config_file/#http-headers
from icecast-metadata-js.
@Yahav Thanks!
from icecast-metadata-js.
Audio streaming service BrLogic.com said they cannot release CORS, this is something they are weighing for the future. Do you know of any services that have this where you don't need to set up an Icecast server?
from icecast-metadata-js.
I understood. Thank you very much. In fact, the metadata, such as the Title, I can say that it is the most important. Although statistics are very useful. Thanks!!!!
from icecast-metadata-js.
Related Issues (20)
- Station name from metadata? HOT 2
- Deferred module loading? HOT 1
- 'IcecastReadableStream' is not exported from 'icecast-metadata-js' (imported as 'IcecastReadableStream') HOT 8
- webaudio analyser ? HOT 3
- Full screen visualizer in demo
- multiple instances of metadata HOT 4
- icecast-metadata-stats NodeJS support HOT 6
- Authenticated streams not working? HOT 4
- CORS or header problem from icecast2 HOT 3
- iOS does not recognize playback correctly
- AbortError with streams from Icecast 2.4.0-kh22 HOT 10
- Uncaught ReferenceError: player is not defined HOT 8
- Play and replay issue on iOS HOT 9
- icecast-metadata-player retry / reconnect logic not working in iOS 17 HOT 1
- icecast-metadata-player - navigator.mediaSession.metadata not working in iOS HOT 3
- Pass custom parameter into icecast-metadata-player-1.17.1.main.min.js HOT 5
- Writing metadata to a file HOT 2
- ReferenceError: Worker is not defined HOT 5
- Audio stops playing after 5 seconds. HOT 4
- Unable to resume audio on iOS 17
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from icecast-metadata-js.