| 54 | } |
| 55 | |
| 56 | async test(stream: Stream): Promise<StreamTesterResult> { |
| 57 | if (TESTING) { |
| 58 | const results = (await import('../../tests/__data__/input/playlist_test/results.js')).default |
| 59 | |
| 60 | return results[stream.url as keyof typeof results] |
| 61 | } else { |
| 62 | try { |
| 63 | const res = await this.client(stream.url, { |
| 64 | signal: AbortSignal.timeout(this.options.timeout), |
| 65 | headers: { |
| 66 | 'User-Agent': stream.user_agent || 'Mozilla/5.0', |
| 67 | Referer: stream.referrer |
| 68 | } |
| 69 | }) |
| 70 | |
| 71 | const mediainfo = await mediaInfoFactory({ format: 'object' }) |
| 72 | const buffer = await res.data |
| 73 | const result = await mediainfo.analyzeData( |
| 74 | () => buffer.byteLength, |
| 75 | (size: number, offset: number) => Buffer.from(buffer).subarray(offset, offset + size) |
| 76 | ) |
| 77 | |
| 78 | if (result && result.media && result.media.track.length > 0) { |
| 79 | return { |
| 80 | status: { |
| 81 | ok: true, |
| 82 | code: 'OK' |
| 83 | } |
| 84 | } |
| 85 | } else { |
| 86 | return { |
| 87 | status: { |
| 88 | ok: false, |
| 89 | code: 'NO_VIDEO' |
| 90 | } |
| 91 | } |
| 92 | } |
| 93 | } catch (err: unknown) { |
| 94 | const error = err as StreamTesterError |
| 95 | |
| 96 | let code = 'UNKNOWN_ERROR' |
| 97 | if (error.name === 'CanceledError') { |
| 98 | code = 'TIMEOUT' |
| 99 | } else if (error.name === 'AxiosError') { |
| 100 | if (error.response) { |
| 101 | const status = error.response?.status |
| 102 | const statusText = error.response?.statusText.toUpperCase().replace(/\s+/, '_') |
| 103 | code = `HTTP_${status}_${statusText}` |
| 104 | } else { |
| 105 | code = `AXIOS_${error.code}` |
| 106 | } |
| 107 | } else if (error.cause) { |
| 108 | const cause = error.cause |
| 109 | if (cause.code) { |
| 110 | code = cause.code |
| 111 | } else { |
| 112 | code = cause.name |
| 113 | } |