Skip to content

Commit 795340b

Browse files
committed
improve: integrate HLSHandler for HLS stream support in Twitter source
1 parent a4db2e5 commit 795340b

File tree

2 files changed

+59
-17
lines changed

2 files changed

+59
-17
lines changed

src/sources/twitch.js

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,17 +558,42 @@ export default class TwitchSource {
558558
return { stream, type: 'mpegts' }
559559
}
560560

561-
const { stream, error, statusCode } = await http1makeRequest(url, {
561+
const { stream: resStream, error, statusCode } = await http1makeRequest(url, {
562+
method: 'GET',
562563
streamOnly: true
563564
})
564-
if (error || statusCode !== 200) {
565+
566+
if (error || statusCode !== 200 || !resStream) {
565567
return {
566568
exception: {
567569
message: `Failed to load stream: ${error?.message || statusCode}`,
568570
severity: 'fault'
569571
}
570572
}
571573
}
574+
575+
const stream = new PassThrough()
576+
577+
resStream.on('data', (chunk) => {
578+
if (!stream.write(chunk)) resStream.pause()
579+
})
580+
581+
stream.on('drain', () => {
582+
if (!resStream.destroyed) resStream.resume()
583+
})
584+
585+
resStream.on('end', () => {
586+
if (!stream.writableEnded) {
587+
stream.emit('finishBuffering')
588+
stream.end()
589+
}
590+
})
591+
592+
resStream.on('error', (err) => {
593+
logger('error', 'Twitch', `External stream error: ${err.message}`)
594+
if (!stream.destroyed) stream.destroy(err)
595+
})
596+
572597
return { stream, type: 'mp4' }
573598
}
574599

src/sources/twitter.js

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { PassThrough } from 'node:stream'
22
import { encodeTrack, http1makeRequest, logger } from '../utils.js'
3+
import HLSHandler from '../playback/hls/HLSHandler.js'
34

45
const AUTH = 'AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA'
56

@@ -207,37 +208,53 @@ export default class TwitterSource {
207208

208209
async loadStream(decodedTrack, url) {
209210
try {
210-
const options = {
211-
method: 'GET',
212-
streamOnly: true,
213-
headers: {
214-
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
215-
'Referer': 'https://twitter.com/'
216-
}
211+
const headers = {
212+
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
213+
'Referer': 'https://twitter.com/'
217214
}
218215

219-
const response = await http1makeRequest(url, options)
216+
if (url.includes('.m3u8')) {
217+
const stream = new HLSHandler(url, {
218+
type: 'fmp4',
219+
strategy: 'segmented',
220+
headers,
221+
localAddress: this.nodelink.routePlanner?.getIP()
222+
})
223+
return { stream, type: 'fmp4' }
224+
}
225+
226+
const response = await http1makeRequest(url, {
227+
method: 'GET',
228+
headers,
229+
streamOnly: true
230+
})
231+
220232
if (response.error || !response.stream) throw response.error || new Error('Failed to get stream')
221233

222234
const stream = new PassThrough()
235+
let finished = false
236+
const finish = () => {
237+
if (finished) return
238+
finished = true
239+
if (!stream.writableEnded) {
240+
stream.emit('finishBuffering')
241+
stream.end()
242+
}
243+
}
223244

224245
response.stream.on('data', (chunk) => {
225246
if (!stream.destroyed) stream.write(chunk)
226247
})
227248

228-
response.stream.on('end', () => {
229-
if (!stream.destroyed) {
230-
stream.emit('finishBuffering')
231-
stream.end()
232-
}
233-
})
249+
response.stream.on('end', finish)
250+
response.stream.on('close', finish)
234251

235252
response.stream.on('error', (err) => {
236253
logger('error', 'Twitter', `External stream error: ${err.message}`)
237254
if (!stream.destroyed) stream.destroy(err)
238255
})
239256

240-
return { stream, type: decodedTrack.pluginInfo?.isHLS ? 'application/x-mpegURL' : 'video/mp4' }
257+
return { stream, type: 'video/mp4' }
241258
} catch (e) {
242259
logger('error', 'Twitter', `Failed to load stream: ${e.message}`)
243260
return { exception: { message: e.message, severity: 'fault' } }

0 commit comments

Comments
 (0)