UNPKG

expo-dlna-player

Version:

A React Native/Expo module for DLNA/AirPlay media casting to smart TVs and streaming devices

367 lines (328 loc) 10.1 kB
import { useEffect, useState } from 'react'; import { DeviceInfo, PlaybackStatus } from './ExpoDlnaPlayer.types'; import ExpoDlnaPlayerModule from './ExpoDlnaPlayerModule'; export * from './ExpoDlnaPlayer.types'; /** * 检查设备是否已连接 * @returns {boolean} 是否已连接到设备 */ export function useDeviceConnectivity() { const [isConnected, setIsConnected] = useState(false); useEffect(() => { // 初始检查 const checkInitialStatus = async () => { try { const connected = await ExpoDlnaPlayerModule.isConnected(); setIsConnected(connected); } catch (error) { console.error('[Expo DLNA Player] 检查连接状态失败:', error); } }; checkInitialStatus(); // 监听连接状态变化 const subscription = ExpoDlnaPlayerModule.addListener( 'onConnectionChanged', (params) => { setIsConnected(params.connected); } ); return () => { subscription.remove(); }; }, []); return isConnected; } /** * 开始搜索可用的DLNA设备 */ export async function startDiscovery(): Promise<void> { try { console.log('[Expo DLNA Player] 开始搜索设备...'); return await ExpoDlnaPlayerModule.startDiscovery(); } catch (error) { console.error('[Expo DLNA Player] 启动设备搜索失败:', error); throw error; } } /** * 停止设备搜索 */ export async function stopDiscovery(): Promise<void> { try { console.log('[Expo DLNA Player] 停止搜索设备'); return await ExpoDlnaPlayerModule.stopDiscovery(); } catch (error) { console.error('[Expo DLNA Player] 停止设备搜索失败:', error); throw error; } } /** * 获取已发现的设备列表 * @returns 设备信息数组 */ export async function getDevices(): Promise<any[]> { try { return await ExpoDlnaPlayerModule.getDevices(); } catch (error) { console.error('[Expo DLNA Player] 获取设备列表失败:', error); throw error; } } /** * 连接到DLNA/AirPlay设备 * @param deviceId 设备ID * @returns 是否连接成功 */ export async function connectToDevice(deviceId: string): Promise<boolean> { try { console.log(`[Expo DLNA Player] 连接到设备: ${deviceId}`); // 获取设备信息 const deviceInfoList = await ExpoDlnaPlayerModule.getDevices(); const device = deviceInfoList.find(d => d.id === deviceId); if (!device) { console.error(`[Expo DLNA Player] 设备未找到: ${deviceId}`); return false; } if (device.type === 'dlna' && !device.controlURL) { console.warn(`[Expo DLNA Player] 警告: DLNA设备缺少controlURL, 设备ID: ${deviceId}`); } return await ExpoDlnaPlayerModule.connectToDevice(deviceId); } catch (error) { console.error('[Expo DLNA Player] 连接设备失败:', error); throw error; } } /** * 断开当前连接的设备 */ export async function disconnectFromDevice(): Promise<void> { try { console.log('[Expo DLNA Player] 断开设备连接'); return await ExpoDlnaPlayerModule.disconnectFromDevice(); } catch (error) { console.error('[Expo DLNA Player] 断开设备连接失败:', error); throw error; } } /** * 检查是否已连接到设备 * @returns 是否已连接 */ export async function isConnected(): Promise<boolean> { try { return await ExpoDlnaPlayerModule.isConnected(); } catch (error) { console.error('[Expo DLNA Player] 检查连接状态失败:', error); throw error; } } /** * 获取当前连接的设备信息 * @returns 设备信息,如果未连接则返回null */ export async function getConnectedDevice(): Promise<any | null> { try { return await ExpoDlnaPlayerModule.getConnectedDevice(); } catch (error) { console.error('[Expo DLNA Player] 获取连接设备信息失败:', error); throw error; } } /** * 播放媒体 * @param url 媒体URL * @param title 媒体标题 * @param mimeType 媒体类型 */ export async function play(url: string, title?: string, mimeType?: string): Promise<void> { try { return await ExpoDlnaPlayerModule.play(url, title, mimeType); } catch (error) { console.error('[Expo DLNA Player] 播放媒体失败:', error); throw error; } } /** * 暂停当前播放 */ export async function pause(): Promise<void> { try { return await ExpoDlnaPlayerModule.pause(); } catch (error) { console.error('[Expo DLNA Player] 暂停播放失败:', error); throw error; } } /** * 恢复播放 */ export async function resume(): Promise<void> { try { return await ExpoDlnaPlayerModule.resume(); } catch (error) { console.error('[Expo DLNA Player] 恢复播放失败:', error); throw error; } } /** * 停止播放 */ export async function stop(): Promise<void> { try { return await ExpoDlnaPlayerModule.stop(); } catch (error) { console.error('[Expo DLNA Player] 停止播放失败:', error); throw error; } } /** * 跳转到指定位置 * @param position 位置(秒) */ export async function seek(position: number): Promise<void> { try { return await ExpoDlnaPlayerModule.seek(position); } catch (error) { console.error('[Expo DLNA Player] 跳转失败:', error); throw error; } } /** * 设置音量 * @param volume 音量(0-100) */ export async function setVolume(volume: number): Promise<void> { try { return await ExpoDlnaPlayerModule.setVolume(volume); } catch (error) { console.error('[Expo DLNA Player] 设置音量失败:', error); throw error; } } /** * 获取播放状态 * @returns 播放状态对象 */ export async function getPlaybackStatus(): Promise<any> { try { return await ExpoDlnaPlayerModule.getPlaybackStatus(); } catch (error) { console.error('[Expo DLNA Player] 获取播放状态失败:', error); throw error; } } /** * 设置播放速率 * @param rate 播放速率(0.5-2.0之间) */ export async function setPlaybackRate(rate: number): Promise<void> { if (!ExpoDlnaPlayerModule.setRate) { console.warn('[Expo DLNA Player] 当前平台不支持设置播放速率'); return; } return await ExpoDlnaPlayerModule.setRate(rate); } /** * 设置静音状态 * @param muted 是否静音 */ export async function setMuted(muted: boolean): Promise<void> { if (!ExpoDlnaPlayerModule.setMuted) { console.warn('[Expo DLNA Player] 当前平台不支持设置静音'); return; } return await ExpoDlnaPlayerModule.setMuted(muted); } /** * 获取媒体缓冲状态 * @returns 返回包含缓冲状态的对象 */ export async function getBufferingStatus(): Promise<object | null> { if (!ExpoDlnaPlayerModule.getBufferingStatus) { console.warn('[Expo DLNA Player] 当前平台不支持获取缓冲状态'); return null; } return await ExpoDlnaPlayerModule.getBufferingStatus(); } /** * 检查当前设备是否支持Miracast投屏功能(仅Android可用) * @returns 是否支持Miracast */ export async function isProjectionSupported(): Promise<boolean> { if (!ExpoDlnaPlayerModule.isProjectionSupported) { console.warn('[Expo DLNA Player] 当前平台不支持Miracast'); return false; } try { return await ExpoDlnaPlayerModule.isProjectionSupported(); } catch (error) { console.error('[Expo DLNA Player] 检查Miracast支持失败:', error); return false; } } /** * 开始Miracast投屏(仅Android可用) * @param deviceId 设备ID * @param mode 投屏模式,可选值: "SCREEN_MIRRORING"(默认) 或 "VIDEO_ONLY" * @returns 是否成功启动投屏 */ export async function startProjection(deviceId: string, mode?: string): Promise<boolean> { if (!ExpoDlnaPlayerModule.startProjection) { console.warn('[Expo DLNA Player] 当前平台不支持Miracast'); return false; } try { return await ExpoDlnaPlayerModule.startProjection(deviceId, mode); } catch (error) { console.error('[Expo DLNA Player] 启动Miracast投屏失败:', error); return false; } } /** * 停止Miracast投屏(仅Android可用) */ export async function stopProjection(): Promise<boolean> { if (!ExpoDlnaPlayerModule.stopProjection) { console.warn('[Expo DLNA Player] 当前平台不支持Miracast'); return false; } try { await ExpoDlnaPlayerModule.stopProjection(); return true; } catch (error) { console.error('[Expo DLNA Player] 停止Miracast投屏失败:', error); return false; } } // 导出核心模块功能 export const ExpoDlnaPlayer = { // 设备发现和管理 startDiscovery: ExpoDlnaPlayerModule.startDiscovery, stopDiscovery: ExpoDlnaPlayerModule.stopDiscovery, getDevices: ExpoDlnaPlayerModule.getDevices as () => Promise<DeviceInfo[]>, // 连接管理 connectToDevice: ExpoDlnaPlayerModule.connectToDevice, disconnectFromDevice: ExpoDlnaPlayerModule.disconnectFromDevice, isConnected: ExpoDlnaPlayerModule.isConnected, getConnectedDevice: ExpoDlnaPlayerModule.getConnectedDevice as () => Promise<DeviceInfo | null>, // 播放控制 play: ExpoDlnaPlayerModule.play, pause: ExpoDlnaPlayerModule.pause, resume: ExpoDlnaPlayerModule.resume, stop: ExpoDlnaPlayerModule.stop, seek: ExpoDlnaPlayerModule.seek, setVolume: ExpoDlnaPlayerModule.setVolume, setRate: ExpoDlnaPlayerModule.setRate, setMuted: ExpoDlnaPlayerModule.setMuted, // 状态查询 getPlaybackStatus: ExpoDlnaPlayerModule.getPlaybackStatus as () => Promise<PlaybackStatus>, getBufferingStatus: ExpoDlnaPlayerModule.getBufferingStatus, // 事件监听 addPlaybackStatusListener: (listener: (status: PlaybackStatus) => void) => ExpoDlnaPlayerModule.addListener('onPlaybackStatusChanged', listener), addConnectionListener: (listener: (event: { deviceId: string, connected: boolean }) => void) => ExpoDlnaPlayerModule.addListener('onConnectionChanged', listener), addErrorListener: (listener: (error: { code: string, message: string }) => void) => ExpoDlnaPlayerModule.addListener('onError', listener), }; export default ExpoDlnaPlayer;