{"id":20172842,"url":"https://github.com/vocadb/nostalgic-diva","last_synced_at":"2025-06-14T15:38:31.295Z","repository":{"id":56871426,"uuid":"526551499","full_name":"VocaDB/nostalgic-diva","owner":"VocaDB","description":"React function components for imperatively controlling embedded players (audio, Niconico, SoundCloud, Vimeo and YouTube) using refs.","archived":false,"fork":false,"pushed_at":"2023-06-07T21:29:29.000Z","size":746,"stargazers_count":4,"open_issues_count":3,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-10T03:14:50.157Z","etag":null,"topics":["audio","embed","html","javascript","nico-nico-douga","niconico","niconicodouga","nnd","player","react","soundcloud","typescript","video","vimeo","vocadb","vocaloid","vocaloid-database","youtube"],"latest_commit_sha":null,"homepage":"https://vocadb.net/Al/12800","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/VocaDB.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-19T09:53:02.000Z","updated_at":"2024-03-12T19:45:48.000Z","dependencies_parsed_at":"2024-10-26T04:11:24.330Z","dependency_job_id":"ba0dd78d-f6fa-4b36-a5f8-1f7876b1d872","html_url":"https://github.com/VocaDB/nostalgic-diva","commit_stats":{"total_commits":121,"total_committers":3,"mean_commits":"40.333333333333336","dds":"0.15702479338842978","last_synced_commit":"c1a2e640aab01c196ed34a4f665c6a073aaf71e6"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VocaDB%2Fnostalgic-diva","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VocaDB%2Fnostalgic-diva/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VocaDB%2Fnostalgic-diva/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/VocaDB%2Fnostalgic-diva/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/VocaDB","download_url":"https://codeload.github.com/VocaDB/nostalgic-diva/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248148243,"owners_count":21055548,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio","embed","html","javascript","nico-nico-douga","niconico","niconicodouga","nnd","player","react","soundcloud","typescript","video","vimeo","vocadb","vocaloid","vocaloid-database","youtube"],"created_at":"2024-11-14T01:32:34.762Z","updated_at":"2025-04-10T03:14:56.787Z","avatar_url":"https://github.com/VocaDB.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nostalgic Diva\n\nReact function components for imperatively controlling embedded players (audio, [Niconico](https://www.nicovideo.jp/), [SoundCloud](https://soundcloud.com/), [Vimeo](https://vimeo.com/) and [YouTube](https://www.youtube.com/)) using refs.\n\nThis was originally developed in [VocaDB/vocadb#1101](https://github.com/VocaDB/vocadb/pull/1101) as a part of VocaDB.\n\nSee [VocaDB](https://vocadb.net/) and [its playlist page](https://vocadb.net/playlist).\n\n## Installation\n\n`yarn add @vocadb/nostalgic-diva` or `npm i @vocadb/nostalgic-diva`\n\n## Usage\n\nFor more information, see [VdbPlayer.tsx](https://github.com/VocaDB/vocadb/blob/dfcb56868a529ea2af508a75a837589caa7cb87f/VocaDbWeb/Scripts/Components/VdbPlayer/VdbPlayer.tsx) and [PlaylistIndex.tsx](https://github.com/VocaDB/vocadb/blob/f84859d9e558341de3b16677adf1699d757fc9a0/VocaDbWeb/Scripts/Pages/Playlist/PlaylistIndex.tsx).\n\n```tsx\nimport {\n\tNostalgicDiva,\n\tNostalgicDivaProvider,\n\tPlayerOptions,\n} from '@aigamo/nostalgic-diva';\n\n// Callbacks\nconst handleError = React.useCallback(() =\u003e {}, []);\nconst handlePlay = React.useCallback(() =\u003e {}, []);\nconst handlePause = React.useCallback(() =\u003e {}, []);\nconst handleEnded = React.useCallback(() =\u003e {}, []);\nconst handleTimeUpdate = React.useCallback(() =\u003e {}, []);\n\n// Options\nconst options = React.useMemo(\n\t(): PlayerOptions =\u003e ({\n\t\tonError: handleError,\n\t\tonPlay: handlePlay,\n\t\tonPause: handlePause,\n\t\tonEnded: handleEnded,\n\t\tonTimeUpdate: handleTimeUpdate,\n\t}),\n\t[handleError, handlePlay, handlePause, handleEnded, handleTimeUpdate],\n);\n\n\u003cNostalgicDivaProvider\u003e\n\t\u003cNostalgicDiva\n\t\t// Supported media types:\n\t\t// - \"Audio\"\n\t\t// - \"Niconico\"\n\t\t// - \"SoundCloud\"\n\t\t// - \"Vimeo\"\n\t\t// - \"YouTube\"\n\t\ttype=\"Audio\"\n\t\tvideoId={videoId}\n\t\toptions={options}\n\t/\u003e\n\t;\n\u003c/NostalgicDivaProvider\u003e;\n```\n\n```tsx\nimport { useNostalgicDiva } from '@aigamo/nostalgic-diva';\n\nconst diva = useNostalgicDiva();\n\n// Play\nawait diva.play();\n\n// Pause\nawait diva.pause();\n\n// Mute\nawait diva.setMuted(true);\n\n// Unmute\nawait diva.setMuted(false);\n\n// Seek\nawait diva.setCurrentTime(seconds);\n```\n\n## Imperative functions\n\n| Function                                         | Description                                                         |\n| ------------------------------------------------ | ------------------------------------------------------------------- |\n| `loadVideo(id: string): Promise\u003cvoid\u003e`           | Loads a new video into an existing player.                          |\n| `play(): Promise\u003cvoid\u003e`                          | Plays a video.                                                      |\n| `pause(): Promise\u003cvoid\u003e`                         | Pauses the playback of a video.                                     |\n| `setCurrentTime(seconds: number): Promise\u003cvoid\u003e` | Sets the current playback position in seconds.                      |\n| `setVolume(volume: number): Promise\u003cvoid\u003e`       | Sets the volume level of the player on a scale from 0 to 1.         |\n| `setMuted(muted: boolean): Promise\u003cvoid\u003e`        | Sets the muted state of the player.                                 |\n| `getDuration(): Promise\u003cnumber \\| undefined\u003e`    | Gets the duration of the video in seconds.                          |\n| `getCurrentTime(): Promise\u003cnumber \\| undefined\u003e` | Gets the current playback position of a video, measured in seconds. |\n\n## Events\n\n| Event                                  | Description                                            |\n| -------------------------------------- | ------------------------------------------------------ |\n| `onError(event: any): void`            | Fired when the player experiences some sort of error.  |\n| `onPlay(): void`                       | Fired when the video plays.                            |\n| `onPause(): void`                      | Fired when the video is paused.                        |\n| `onEnded(): void`                      | Fired when playback reaches the end of a video.        |\n| `onTimeUpdate(event: TimeEvent): void` | Fired when the playback position of the video changes. |\n\n## Lifecycle\n\n1. [PlayerApi.attach](https://github.com/VocaDB/nostalgic-diva/blob/5cc35c68cf71230f9459804a9dd9e9265cfa2297/src/players/PlayerApi.ts#L84)\n1. [IPlayerApi.loadVideo](https://github.com/VocaDB/nostalgic-diva/blob/5cc35c68cf71230f9459804a9dd9e9265cfa2297/src/players/PlayerApi.ts#L33)\n1. [PlayerOptions.onLoaded](https://github.com/VocaDB/nostalgic-diva/blob/5cc35c68cf71230f9459804a9dd9e9265cfa2297/src/players/PlayerApi.ts#L25)\n1. [IPlayerApi.play](https://github.com/VocaDB/nostalgic-diva/blob/5cc35c68cf71230f9459804a9dd9e9265cfa2297/src/players/PlayerApi.ts#L34)\n1. [PlayerOptions.onPlay](https://github.com/VocaDB/nostalgic-diva/blob/5cc35c68cf71230f9459804a9dd9e9265cfa2297/src/players/PlayerApi.ts#L26)\n1. [PlayerOptions.onTimeUpdate](https://github.com/VocaDB/nostalgic-diva/blob/5cc35c68cf71230f9459804a9dd9e9265cfa2297/src/players/PlayerApi.ts#L29)\n1. [IPlayerApi.pause](https://github.com/VocaDB/nostalgic-diva/blob/5cc35c68cf71230f9459804a9dd9e9265cfa2297/src/players/PlayerApi.ts#L35)\n1. [PlayerOptions.onPause](https://github.com/VocaDB/nostalgic-diva/blob/5cc35c68cf71230f9459804a9dd9e9265cfa2297/src/players/PlayerApi.ts#L27)\n1. [PlayerOptions.onEnded](https://github.com/VocaDB/nostalgic-diva/blob/5cc35c68cf71230f9459804a9dd9e9265cfa2297/src/players/PlayerApi.ts#L28)\n1. [PlayerApi.detach](https://github.com/VocaDB/nostalgic-diva/blob/5cc35c68cf71230f9459804a9dd9e9265cfa2297/src/players/PlayerApi.ts#L111)\n\nThe `attach` function is called when switching from another player (Audio, Niconico, SoundCloud and YouTube), and the `detach` function is called when switching to another player. After the `detach` function is called, you cannot use any imperative functions like `loadVideo`, `play`, `pause` and etc.\n\n## References\n\n-   [vocadb/VocaDbWeb/Scripts/ViewModels/PVs/](https://github.com/VocaDB/vocadb/tree/5304e764cf423f07b424e94266e415db40d11f28/VocaDbWeb/Scripts/ViewModels/PVs)\n-   [React Player](https://github.com/cookpete/react-player)\n-   [ニコニコ動画の HTML5 外部プレイヤーを JavaScript で操作する](https://blog.hayu.io/web/create/nicovideo-embed-player-api/)\n-   [Widget API - SoundCloud Developers](https://developers.soundcloud.com/docs/api/html5-widget)\n-   [Player SDK: Reference - Vimeo Developer](https://developer.vimeo.com/player/sdk/reference)\n-   [YouTube Player API Reference for iframe Embeds | YouTube IFrame Player API | Google Developers](https://developers.google.com/youtube/iframe_api_reference)\n-   [How to support Reusable State in Effects · Discussion #18 · reactwg/react-18](https://github.com/reactwg/react-18/discussions/18)\n-   [Synchronizing with Effects](https://beta.reactjs.org/learn/synchronizing-with-effects#how-to-handle-the-effect-firing-twice-in-development)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvocadb%2Fnostalgic-diva","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvocadb%2Fnostalgic-diva","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvocadb%2Fnostalgic-diva/lists"}