Code Monkey home page Code Monkey logo

Comments (25)

eshaz avatar eshaz commented on July 30, 2024 1

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.

eshaz avatar eshaz commented on July 30, 2024 1

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.

eshaz avatar eshaz commented on July 30, 2024

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.

michaelschufi avatar michaelschufi commented on July 30, 2024

Hi

Thanks for your quick reply!

I've tried it, using this process:

  1. Clone the repo and checkout the branch fix-exports.
  2. Link the icecast-metadata-player and icecast-metadata-js packages using npm link in the specific folders in /src as global npm packages on my machine.
  3. Using the packages inside my project using npm link icecast-metadata-player and npm link icecast-metadata-js.
  4. Import the player import IcecastMetadataPlayer from 'icecast-metadata-player';
  5. 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.

eshaz avatar eshaz commented on July 30, 2024

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:

  1. Change "icecast-metadata-player": "1.2.2", to "icecast-metadata-player": "file:../icecast-metadata-js/src/icecast-metadata-player" in package.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"
      },
    
  2. Run npm i
  3. Run npm start

from icecast-metadata-js.

michaelschufi avatar michaelschufi commented on July 30, 2024

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.

eshaz avatar eshaz commented on July 30, 2024

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.

michaelschufi avatar michaelschufi commented on July 30, 2024

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.

eshaz avatar eshaz commented on July 30, 2024

@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.

michaelschufi avatar michaelschufi commented on July 30, 2024

@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.

oseiasmribeiro avatar oseiasmribeiro commented on July 30, 2024

Is there any chance the Player will work in Next JS 13? I really need to extract the metadata.

from icecast-metadata-js.

eshaz avatar eshaz commented on July 30, 2024

It should work, as long as icecast-metadata-player is only loaded client side.

from icecast-metadata-js.

oseiasmribeiro avatar oseiasmribeiro commented on July 30, 2024

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.

eshaz avatar eshaz commented on July 30, 2024

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.

oseiasmribeiro avatar oseiasmribeiro commented on July 30, 2024

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.

oseiasmribeiro avatar oseiasmribeiro commented on July 30, 2024

image

Trying something similar to the example given above of michaelschufi, I get a warning only when accessing through the browser.

image

from icecast-metadata-js.

eshaz avatar eshaz commented on July 30, 2024

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.

oseiasmribeiro avatar oseiasmribeiro commented on July 30, 2024

image

With this code I no longer have the previous errors. Now I am having CORS error. Any suggestion?

image

from icecast-metadata-js.

eshaz avatar eshaz commented on July 30, 2024

Take a look at the readme on CORS and the other git issues tagged CORS.

from icecast-metadata-js.

oseiasmribeiro avatar oseiasmribeiro commented on July 30, 2024

image

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.

oseiasmribeiro avatar oseiasmribeiro commented on July 30, 2024

happy!

image

image

With your example URL it works. It looks like my Stream server doesn't have Cors for all origins.

from icecast-metadata-js.

Yahav avatar Yahav commented on July 30, 2024

@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.

oseiasmribeiro avatar oseiasmribeiro commented on July 30, 2024

@Yahav Thanks!

from icecast-metadata-js.

oseiasmribeiro avatar oseiasmribeiro commented on July 30, 2024

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.

oseiasmribeiro avatar oseiasmribeiro commented on July 30, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.