Merge branch 'feat/player-local-subtitles' of https://github.com/Stremio/stremio-web into feat/player-local-subtitles

This commit is contained in:
Tim 2025-02-07 11:30:08 +01:00
commit caf9ba1c7f
5 changed files with 39 additions and 9 deletions

View file

@ -41,6 +41,11 @@ const ICON_FOR_TYPE = new Map([
['other', 'movies'],
]);
const MIME_SIGNATURES = {
'application/x-subrip': ['310D0A', '310A'],
'text/vtt': ['574542565454'],
};
const SUPPORTED_LOCAL_SUBTITLES = [
'application/x-subrip',
'text/vtt',
@ -118,6 +123,7 @@ module.exports = {
WRITERS_LINK_CATEGORY,
TYPE_PRIORITIES,
ICON_FOR_TYPE,
MIME_SIGNATURES,
SUPPORTED_LOCAL_SUBTITLES,
EXTERNAL_PLAYERS,
WHITELISTED_HOSTS,

View file

@ -1,8 +1,9 @@
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
import classNames from 'classnames';
import { isFileType } from './utils';
export type FileType = string;
export type FileDropListener = (file: File) => void;
export type FileDropListener = (filename: string, buffer: ArrayBuffer) => void;
type FileDropContext = {
on: (type: FileType, listener: FileDropListener) => void,
@ -31,15 +32,18 @@ const FileDropProvider = ({ className, children }: Props) => {
const onDrop = useCallback((event: DragEvent) => {
event.preventDefault();
const { dataTransfer } = event;
if (dataTransfer && dataTransfer.files.length > 0) {
if (dataTransfer && dataTransfer?.files.length > 0) {
const file = dataTransfer.files[0];
listeners
.filter(([type]) => type === file.type)
.forEach(([, listerner]) => listerner(file));
file
.arrayBuffer()
.then((buffer) => {
listeners
.filter(([type]) => file.type ? type === file.type : isFileType(buffer, type))
.forEach(([, listerner]) => listerner(file.name, buffer));
});
}
setActive(false);

View file

@ -0,0 +1,19 @@
import { MIME_SIGNATURES } from 'stremio/common/CONSTANTS';
const SIGNATURES = MIME_SIGNATURES as Record<string, string[]>;
const isFileType = (buffer: ArrayBuffer, type: string) => {
const signatures = SIGNATURES[type];
return signatures.some((signature) => {
const array = new Uint8Array(buffer);
const signatureBuffer = Buffer.from(signature, 'hex');
const bufferToCompare = array.subarray(0, signatureBuffer.length);
return Buffer.compare(signatureBuffer, bufferToCompare) === 0;
});
};
export {
isFileType,
};

View file

@ -277,9 +277,8 @@ const Player = ({ urlParams, queryParams }) => {
event.nativeEvent.immersePrevented = true;
}, []);
onFileDrop(CONSTANTS.SUPPORTED_LOCAL_SUBTITLES, async (file) => {
const buffer = await file.arrayBuffer();
video.addLocalSubtitles(file.name, buffer);
onFileDrop(CONSTANTS.SUPPORTED_LOCAL_SUBTITLES, async (filename, buffer) => {
video.addLocalSubtitles(filename, buffer);
});
React.useEffect(() => {

View file

@ -40,6 +40,8 @@ function DragAndDrop({ core }) {
break;
case 'text/vtt':
break;
case '':
break;
default: {
events.emit('error', {
message: 'Unsupported file',