Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@profullstack/player",
"version": "0.2.0",
"version": "0.3.0",
"description": "One web player for every source a Profullstack site serves: MP4, HLS, MPEG-2 transport streams and audio, with one control bar, on desktop, mobile, PWA and television.",
"keywords": [
"video",
Expand Down Expand Up @@ -32,6 +32,10 @@
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./codecs": {
"types": "./dist/codecs.d.ts",
"default": "./dist/codecs.js"
},
"./react": {
"types": "./dist/react/index.d.ts",
"default": "./dist/react/index.js"
Expand Down
16 changes: 16 additions & 0 deletions src/codecs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* The codec table on its own, with no player attached.
*
* genrewatch and tipoffwatch each carry a copy of this file. It is the most
* expensive 150 lines in either repo -- every rule in it was written in
* response to a channel that failed in production, and two of them were got
* wrong twice -- and three copies of it is exactly the thing this package
* exists to stop.
*
* A subpath rather than the root export, because those two bundle their client
* by hand and are careful about its weight: importing from the root would pull
* the player and its dynamic engine imports into a bundle that wants a lookup
* table and nothing else.
*/

export { codecName, mseCandidates, unplayableReason, type MediaInfoLike } from './engines/codecs';
9 changes: 7 additions & 2 deletions src/engines/codecs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,16 @@ export function mseCandidates(kind: 'video' | 'audio', codec: string | undefined
* is testable without a browser.
* @param advice appended when there is a problem — the host site's suggestion
* for what to do instead, which this package cannot know.
* @param subject what the thing is called on the host site. genrewatch and
* tipoffwatch say "channel" because that is what their reader clicked; a
* recording is a "stream" at best. Naming it wrongly is a small thing that
* makes shared copy read as though it came from somewhere else.
*/
export function unplayableReason(
info: MediaInfoLike | null | undefined,
isTypeSupported: (type: string) => boolean,
advice = ''
advice = '',
subject = 'stream'
): string | null {
if (!info || typeof isTypeSupported !== 'function') return null;

Expand Down Expand Up @@ -158,5 +163,5 @@ export function unplayableReason(
// Both halves unplayable is one sentence, not two: the reader is going
// elsewhere either way, and listing two problems reads as two things to fix.
const what = bad.length === 1 ? bad[0] : `${String(bad[0])} and ${String(bad[1])}`;
return `This stream is ${String(what)}, which this browser cannot decode.${advice ? ` ${advice}` : ''}`;
return `This ${subject} is ${String(what)}, which this browser cannot decode.${advice ? ` ${advice}` : ''}`;
}
7 changes: 7 additions & 0 deletions test/codecs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,13 @@ describe('unplayableReason', () => {
);
});

it('lets the host name the thing its reader clicked', () => {
// genrewatch and tipoffwatch say "channel"; a recording is a "stream".
expect(unplayableReason({ videoCodec: 'hvc1.1' }, supports([]), '', 'channel')).toBe(
'This channel is H.265, which this browser cannot decode.'
);
});

it('appends the host site’s advice when given some', () => {
const reason = unplayableReason({ videoCodec: 'hvc1.1' }, supports([]), 'Try VLC.');
expect(reason).toBe('This stream is H.265, which this browser cannot decode. Try VLC.');
Expand Down
2 changes: 1 addition & 1 deletion tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { defineConfig } from 'tsup';
* anyone who already has one.
*/
export default defineConfig({
entry: ['src/index.ts', 'src/react/index.tsx'],
entry: ['src/index.ts', 'src/react/index.tsx', 'src/codecs.ts'],
format: ['esm'],
target: 'es2022',
splitting: true,
Expand Down
Loading