Skip to content

Commit

Permalink
feat(web): add a web implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
jspizziri committed Jan 24, 2023
1 parent c3d8b5f commit cd8dcbe
Show file tree
Hide file tree
Showing 28 changed files with 681 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
root = true

[{src,scripts}/**.{ts,json,js}]
[{src,web,scripts}/**.{ts,json,js}]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -273,3 +273,14 @@ You can find us as part of the [React Native Track Player](https://discordapp.co
- `# support` - Ask members of the community to trouble shoot issues with your app and make recommendations.
- `# app-anouncements` - Tell the community about the app you made with this project!
- `# releases` - Stay updated about the latest releases and dev efforts on the project.


### Web Notes

https://github.com/shaka-project/shaka-player/blob/7772099029acb47e6905a688f6cfc9c8738c6ff2/docs/tutorials/faq.md

Q: Why doesn't my HLS content work?

A: If your HLS content uses MPEG2-TS, you may need to enable transmuxing. The only browsers capable of playing TS natively are Edge and Chromecast. You will get a CONTENT_UNSUPPORTED_BY_BROWSER error on other browsers due to their lack of TS support.

You can enable transmuxing by including mux.js v5.6.3+ in your application. If Shaka Player detects that mux.js has been loaded, we will use it to transmux TS content into MP4 on-the-fly, so that the content can be played by the browser.
1 change: 1 addition & 0 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
},
"dependencies": {
"@react-native-community/slider": "^4.4.0",
"mux.js": "^6.2.0",
"react": "17.0.2",
"react-dom": "^17.0.2",
"react-native": "0.68.1",
Expand Down
Binary file added example/public/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion example/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<title>Your App Title</title>
<link rel="icon" type="image/png" href="/icon.png">
<title>RNTP Example App</title>
</head>

<body>
Expand Down
2 changes: 2 additions & 0 deletions example/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
StatusBar,
StyleSheet,
View,
Platform,
} from 'react-native';
import TrackPlayer, { useActiveTrack } from 'react-native-track-player';

Expand Down Expand Up @@ -67,6 +68,7 @@ const styles = StyleSheet.create({
backgroundColor: '#212121',
alignItems: 'center',
justifyContent: 'center',
minHeight: Platform.OS === 'web' ? '100vh' : '100%',
},
contentContainer: {
flex: 3,
Expand Down
4 changes: 2 additions & 2 deletions example/src/components/Progress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const Progress: React.FC<{ live?: boolean }> = ({ live }) => {
<Text style={styles.liveText}>Live Stream</Text>
</View>
) : (
<>
<View>
<Slider
style={styles.container}
value={position}
Expand All @@ -27,7 +27,7 @@ export const Progress: React.FC<{ live?: boolean }> = ({ live }) => {
{formatSeconds(Math.max(0, duration - position))}
</Text>
</View>
</>
</View>
);
};

Expand Down
5 changes: 5 additions & 0 deletions example/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
************************************************/
import {AppRegistry} from 'react-native';
import App from './App';
import TrackPlayer from 'react-native-track-player';
import {PlaybackService} from './services';
import 'mux.js';

const appName = 'Your app name';

Expand All @@ -11,3 +14,5 @@ AppRegistry.runApplication(appName, {
// Mount the react-native app in the 'root' div of index.html
rootTag: document.getElementById('root'),
});

TrackPlayer.registerPlaybackService(() => PlaybackService);
5 changes: 5 additions & 0 deletions example/src/services/PlaybackService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ export async function PlaybackService() {
console.log('Event.PlaybackActiveTrackChanged', event);
});

TrackPlayer.addEventListener(Event.PlaybackProgressUpdated, (event) => {
console.log('Event.PlaybackProgressUpdated', event);
});


TrackPlayer.addEventListener(Event.PlaybackPlayWhenReadyChanged, (event) => {
console.log('Event.PlaybackPlayWhenReadyChanged', event);
});
Expand Down
33 changes: 33 additions & 0 deletions example/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5071,6 +5071,11 @@ dom-serializer@^1.0.1:
domhandler "^4.2.0"
entities "^2.0.0"

dom-walk@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84"
integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==

domelementtype@1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
Expand Down Expand Up @@ -6385,6 +6390,14 @@ global-prefix@^3.0.0:
kind-of "^6.0.2"
which "^1.3.1"

global@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
dependencies:
min-document "^2.19.0"
process "^0.11.10"

globals@^11.1.0:
version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
Expand Down Expand Up @@ -9268,6 +9281,13 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0:
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==

min-document@^2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==
dependencies:
dom-walk "^0.1.0"

mini-css-extract-plugin@^2.4.5:
version "2.7.2"
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.2.tgz#e049d3ea7d3e4e773aad585c6cb329ce0c7b72d7"
Expand Down Expand Up @@ -9342,6 +9362,14 @@ mustache@^4.0.1:
resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64"
integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==

mux.js@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/mux.js/-/mux.js-6.2.0.tgz#158a4fcf5d83b087ab9037d325527ea993f830a3"
integrity sha512-SKuxIcbmK/aJoz78aQNuoXY8R/uEPm1gQMqWTXL6DNl7oF8UPjdt/AunXGkPQpBouGWKDgL/TzSl2VV5NuboRg==
dependencies:
"@babel/runtime" "^7.11.2"
global "^4.4.0"

nan@^2.12.1:
version "2.17.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb"
Expand Down Expand Up @@ -10647,6 +10675,11 @@ process-nextick-args@~2.0.0:
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==

process@^0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==

promise@^7.1.1:
version "7.3.1"
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
Expand Down
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"name": "react-native-track-player",
"version": "3.2.0",
"description": "A fully fledged audio module created for music apps",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"main": "lib/src/index.js",
"types": "lib/src/index.d.ts",
"react-native": "src/index",
"source": "src/index",
"scripts": {
Expand Down Expand Up @@ -31,6 +31,7 @@
"lib/**/*",
"ios/**/*",
"android/**/*",
"web/**/*",
"*.podspec"
],
"contributors": [
Expand Down Expand Up @@ -93,15 +94,18 @@
"eslint-plugin-react-hooks": "^4.6.0",
"husky": "^8.0.0",
"prettier": "^2.7.1",
"rimraf": "^2.6.2",
"react": "17.0.2",
"react-native": "0.68.1",
"react-native-windows": "^0.65.0-0",
"rimraf": "^2.6.2",
"typescript": "^4.8.2"
},
"config": {
"commitizen": {
"path": "cz-conventional-changelog"
}
},
"dependencies": {
"shaka-player": "^4.3.2"
}
}
3 changes: 3 additions & 0 deletions src/TrackPlayerModule.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { NativeModules } from 'react-native'
const { TrackPlayerModule } = NativeModules
export default TrackPlayerModule;
2 changes: 2 additions & 0 deletions src/TrackPlayerModule.web.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import TrackPlayerModule from '../web';
export default TrackPlayerModule;
3 changes: 1 addition & 2 deletions src/constants/Capability.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { NativeModules } from 'react-native';
const { TrackPlayerModule: TrackPlayer } = NativeModules;
import TrackPlayer from '../TrackPlayerModule';

export enum Capability {
Play = TrackPlayer.CAPABILITY_PLAY,
Expand Down
3 changes: 1 addition & 2 deletions src/constants/PitchAlgorithm.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { NativeModules } from 'react-native';
const { TrackPlayerModule: TrackPlayer } = NativeModules;
import TrackPlayer from '../TrackPlayerModule';

export enum PitchAlgorithm {
/**
Expand Down
3 changes: 1 addition & 2 deletions src/constants/RatingType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { NativeModules } from 'react-native';
const { TrackPlayerModule: TrackPlayer } = NativeModules;
import TrackPlayer from '../TrackPlayerModule';

export enum RatingType {
Heart = TrackPlayer.RATING_HEART,
Expand Down
3 changes: 1 addition & 2 deletions src/constants/RepeatMode.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { NativeModules } from 'react-native';
const { TrackPlayerModule: TrackPlayer } = NativeModules;
import TrackPlayer from '../TrackPlayerModule';

export enum RepeatMode {
/** Playback stops when the last track in the queue has finished playing. */
Expand Down
3 changes: 3 additions & 0 deletions src/resolveAssetSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// @ts-expect-error because resolveAssetSource is untyped
import resolve from 'react-native/Libraries/Image/resolveAssetSource';
export default resolve;
10 changes: 10 additions & 0 deletions src/resolveAssetSource.web.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const resolveAssetResource = (base64: any) => {
if (/^https?:\/\//.test(base64)) {
return base64;
}

// TODO: resolveAssetResource for web
return base64;
}

export default resolveAssetResource;
10 changes: 4 additions & 6 deletions src/trackPlayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import {
AppRegistry,
DeviceEventEmitter,
NativeEventEmitter,
NativeModules,
Platform,
} from 'react-native';

import TrackPlayer from './TrackPlayerModule';
import { Event, RepeatMode, State } from './constants';
import type {
EventPayloadByEvent,
Expand All @@ -18,12 +18,8 @@ import type {
TrackMetadataBase,
UpdateOptions,
} from './interfaces';
import resolveAssetSource from './resolveAssetSource';

// the Image.resolveAssetResource is the same as the raw import, but it works with web
// so use it here. Use a `require` to avoid typescript inconsistencies.
const resolveAssetSource = require('react-native').Image.resolveAssetSource;

const { TrackPlayerModule: TrackPlayer } = NativeModules;
const emitter =
Platform.OS !== 'android'
? new NativeEventEmitter(TrackPlayer)
Expand Down Expand Up @@ -55,6 +51,8 @@ export function registerPlaybackService(factory: () => ServiceHandler) {
if (Platform.OS === 'android') {
// Registers the headless task
AppRegistry.registerHeadlessTask('TrackPlayer', factory);
} else if (Platform.OS === 'web') {
factory()();
} else {
// Initializes and runs the service in the next tick
setImmediate(factory());
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"esModuleInterop": true,
"isolatedModules": true,
"jsx": "react-native",
"lib": ["es2017"],
"lib": ["es2017", "DOM", "DOM.Iterable"],
"moduleResolution": "node",
"outDir": "./lib",
"strict": true,
Expand Down
Loading

0 comments on commit cd8dcbe

Please sign in to comment.