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
text/typescript
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;