Skip to content

Commit

Permalink
feat: accept tvp url and fetch m3u8 playlist under the hood
Browse files Browse the repository at this point in the history
  • Loading branch information
bpawel10 committed Nov 26, 2022
1 parent ed01b1e commit 5e75592
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 10 deletions.
64 changes: 54 additions & 10 deletions src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { Component } from 'solid-js';
import { createSignal, Show } from 'solid-js';
import { Tvp } from './providers/tvp';
import { Watch } from './watch';

export const App: Component = () => {
const [videoUrl, setVideoUrl] = createSignal('');
const [chatUrl, setChatUrl] = createSignal('');
const [video, setVideo] = createSignal<URL | null>();
const [play, setPlay] = createSignal(false);

return (
Expand All @@ -16,15 +18,57 @@ export const App: Component = () => {
<div class="flex flex-col w-full items-center gap-4">
<div class="w-4/5">
<label class="text-white">Video url</label>
<input
type="text"
class="w-full px-2 py-1 rounded-sm"
placeholder="Video url"
value={videoUrl()}
onInput={({ currentTarget: { value } }) =>
setVideoUrl(() => value)
}
/>
<div class="relative">
<input
type="text"
class="w-full px-2 py-1 rounded-sm"
placeholder="Video url"
value={videoUrl()}
onInput={async ({ currentTarget: { value } }) => {
setVideoUrl(() => value);
try {
const video = await new Tvp().parse(new URL(value));
setVideo(video);
} catch (_) {
setVideo(null);
}
}}
/>
<div class="absolute -right-7" style={{ top: '1px' }}>
<Show when={video() !== undefined}>
<Show
when={video()}
fallback={
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="w-6 h-6 text-red-600"
>
<path
fill-rule="evenodd"
d="M12 2.25c-5.385 0-9.75 4.365-9.75 9.75s4.365 9.75 9.75 9.75 9.75-4.365 9.75-9.75S17.385 2.25 12 2.25zm-1.72 6.97a.75.75 0 10-1.06 1.06L10.94 12l-1.72 1.72a.75.75 0 101.06 1.06L12 13.06l1.72 1.72a.75.75 0 101.06-1.06L13.06 12l1.72-1.72a.75.75 0 10-1.06-1.06L12 10.94l-1.72-1.72z"
clip-rule="evenodd"
/>
</svg>
}
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
class="w-6 h-6 text-green-600"
>
<path
fill-rule="evenodd"
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm13.36-1.814a.75.75 0 10-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 00-1.06 1.06l2.25 2.25a.75.75 0 001.14-.094l3.75-5.25z"
clip-rule="evenodd"
/>
</svg>
</Show>
</Show>
</div>
</div>
</div>
<div class="w-4/5">
<label class="text-white">Chat url</label>
Expand All @@ -49,7 +93,7 @@ export const App: Component = () => {
</div>
}
>
<Watch videoUrl={new URL(videoUrl())} chatUrl={new URL(chatUrl())} />
<Watch videoUrl={video()!} chatUrl={new URL(chatUrl())} />
</Show>
);
};
1 change: 1 addition & 0 deletions src/interfaces/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './chat.interface';
export * from './message.interface';
export * from './video.interface';
3 changes: 3 additions & 0 deletions src/interfaces/video.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface IVideo {
parse(url: URL): Promise<URL>;
}
21 changes: 21 additions & 0 deletions src/providers/tvp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { fetch, ResponseType } from '@tauri-apps/api/http';
import { IVideo } from '../interfaces';

export class Tvp implements IVideo {
async parse(url: URL): Promise<URL> {
const { data } = await fetch<string>(url.toString(), {
method: 'GET',
responseType: ResponseType.Text,
});
const [, videoId] = data.replace(/\s+/g, '').match(/"video_id":(\d+)/)!;
const { data: json } = await fetch<Record<string, any>>(
`https://api.tvp.pl/tokenizer/token/${videoId}`,
);
return new URL(
json.formats.find(
({ mimeType }: { mimeType: string }) =>
mimeType === 'application/x-mpegurl',
).url,
);
}
}

0 comments on commit 5e75592

Please sign in to comment.