mirror of
https://github.com/tapframe/NuvioStreaming.git
synced 2026-05-17 23:42:04 +00:00
feat: implement torrent streaming support
Added react-native-torrent-streamer and TorrentService. Enabled magnet link forwarding to external players.
This commit is contained in:
parent
5f49a7f2ab
commit
2d85094508
4 changed files with 97 additions and 6 deletions
|
|
@ -92,6 +92,7 @@
|
|||
"react-native-safe-area-context": "~5.7.0",
|
||||
"react-native-screens": "^4.24.0",
|
||||
"react-native-svg": "^15.15.3",
|
||||
"react-native-torrent-streamer": "^0.2.3",
|
||||
"react-native-url-polyfill": "^3.0.0",
|
||||
"react-native-vector-icons": "^10.3.0",
|
||||
"react-native-video": "^6.19.0",
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import { localScraperService } from '../../services/pluginService';
|
|||
import { VideoPlayerService } from '../../services/videoPlayerService';
|
||||
import { streamCacheService } from '../../services/streamCacheService';
|
||||
import { tmdbService } from '../../services/tmdbService';
|
||||
import { torrentService } from '../../services/torrentService';
|
||||
import { logger } from '../../utils/logger';
|
||||
import { TABLET_BREAKPOINT } from './constants';
|
||||
import {
|
||||
|
|
@ -463,10 +464,26 @@ export const useStreamsScreen = () => {
|
|||
});
|
||||
}
|
||||
|
||||
// Block magnet links
|
||||
if (typeof stream.url === 'string' && stream.url.startsWith('magnet:')) {
|
||||
openAlert('Not supported', 'Torrent streaming is not supported yet.');
|
||||
return;
|
||||
// Let external players handle magnet links
|
||||
const isMagnet = typeof stream.url === 'string' && stream.url.startsWith('magnet:');
|
||||
|
||||
// Process magnet links via the torrent service if using internal player
|
||||
if (isMagnet && settings.preferredPlayer === 'internal' && !settings.useExternalPlayer) {
|
||||
if (Platform.OS === 'android') {
|
||||
try {
|
||||
if (showInfo) showInfo('Starting Torrent Stream... Please wait.');
|
||||
const localUrl = await torrentService.startStreaming(stream.url as string);
|
||||
const torrentStream = { ...stream, url: localUrl };
|
||||
navigateToPlayer(torrentStream);
|
||||
return;
|
||||
} catch (err) {
|
||||
openAlert('Torrent Error', 'Failed to start the torrent stream.');
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
openAlert('Not supported internally', 'Internal torrent streaming is only supported on Android. Please use an external player.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// iOS external player
|
||||
|
|
|
|||
71
src/services/torrentService.ts
Normal file
71
src/services/torrentService.ts
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import { Platform } from 'react-native';
|
||||
import { logger } from '../utils/logger';
|
||||
|
||||
// @ts-ignore - Module might not have types
|
||||
import TorrentStreamer from 'react-native-torrent-streamer';
|
||||
|
||||
export const torrentService = {
|
||||
startStreaming: (url: string): Promise<string> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (Platform.OS !== 'android') {
|
||||
reject(new Error('Torrent streaming natively is only supported on Android.'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
TorrentStreamer.start(url);
|
||||
|
||||
const onReady = (data: any) => {
|
||||
logger.log('[TorrentService] Torrent is ready at:', data.url);
|
||||
// Remove listener once resolved to prevent memory leaks
|
||||
TorrentStreamer.removeEventListener('ready', onReady);
|
||||
resolve(data.url);
|
||||
};
|
||||
|
||||
const onError = (error: any) => {
|
||||
logger.error('[TorrentService] Error streaming torrent:', error);
|
||||
TorrentStreamer.removeEventListener('error', onError);
|
||||
reject(error);
|
||||
};
|
||||
|
||||
TorrentStreamer.addEventListener('ready', onReady);
|
||||
TorrentStreamer.addEventListener('error', onError);
|
||||
|
||||
} catch (err) {
|
||||
logger.error('[TorrentService] Initialization error:', err);
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
stopStreaming: () => {
|
||||
if (Platform.OS === 'android') {
|
||||
try {
|
||||
TorrentStreamer.stop();
|
||||
logger.log('[TorrentService] Stopped torrent stream.');
|
||||
} catch (err) {
|
||||
logger.error('[TorrentService] Failed to stop stream:', err);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
addListener: (event: 'status' | 'ready' | 'error', callback: (data: any) => void) => {
|
||||
if (Platform.OS === 'android') {
|
||||
try {
|
||||
TorrentStreamer.addEventListener(event, callback);
|
||||
} catch (err) {
|
||||
logger.warn('[TorrentService] Could not add listener:', err);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
removeListener: (event: 'status' | 'ready' | 'error', callback: (data: any) => void) => {
|
||||
if (Platform.OS === 'android') {
|
||||
try {
|
||||
TorrentStreamer.removeEventListener(event, callback);
|
||||
} catch (err) {
|
||||
logger.warn('[TorrentService] Could not remove listener:', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -29,11 +29,13 @@ export const VideoPlayerService = {
|
|||
options.releaseDate
|
||||
].filter(Boolean).join(' - ');
|
||||
|
||||
// Launch the intent to play the video
|
||||
// Launch the intent to play the video or handle the magnet link
|
||||
const isMagnet = url.startsWith('magnet:');
|
||||
|
||||
await IntentLauncher.startActivityAsync('android.intent.action.VIEW', {
|
||||
data: url,
|
||||
flags: 1, // FLAG_ACTIVITY_NEW_TASK
|
||||
type: 'video/*',
|
||||
type: isMagnet ? 'application/x-bittorrent' : 'video/*',
|
||||
extra: {
|
||||
'android.intent.extra.TITLE': fullTitle,
|
||||
'position': 0, // Start from beginning
|
||||
|
|
|
|||
Loading…
Reference in a new issue