|
1 | 1 | import {base64Decode} from '../libs_drpy/crypto-util.js';
|
2 | 2 | import '../utils/random-http-ua.js'
|
3 | 3 | import {keysToLowerCase} from '../utils/utils.js';
|
| 4 | +import {ENV} from "../utils/env.js"; |
| 5 | +import chunkStream, {testSupport} from '../utils/chunk.js'; |
4 | 6 | import http from 'http';
|
5 | 7 | import https from 'https';
|
6 | 8 | import axios from 'axios';
|
@@ -36,80 +38,30 @@ export default (fastify, options, done) => {
|
36 | 38 | : {};
|
37 | 39 |
|
38 | 40 | // Call the proxy function, passing the decoded URL and headers
|
39 |
| - // return await proxyStreamMedia(decodedUrl, decodedHeader, reply); |
40 |
| - return await proxyStreamMediaMulti(decodedUrl, decodedHeader, request, reply, thread, size, randUa); |
| 41 | + // return await proxyStreamMediaMulti(decodedUrl, decodedHeader, request, reply, thread, size, randUa); |
| 42 | + // return await chunkStream(request, reply, decodedUrl, ids[1], Object.assign({Cookie: cookie}, baseHeader)); |
| 43 | + if (ENV.get('play_proxy_mode', '1') !== '2') { // 2磁盘加速 其他都是内存加速 |
| 44 | + console.log('[mediaProxy] proxyStreamMediaMulti 内存加速:chunkSize:', sizeToBytes(size)); |
| 45 | + return await proxyStreamMediaMulti(decodedUrl, decodedHeader, request, reply, thread, size, randUa); |
| 46 | + } else { |
| 47 | + console.log('[mediaProxy] chunkStream 磁盘加速 chunkSize:', sizeToBytes('256K')); |
| 48 | + return await chunkStream(request, reply, decodedUrl, null, decodedHeader, |
| 49 | + Object.assign({chunkSize: 1024 * 256, poolSize: 5, timeout: 1000 * 10}, { |
| 50 | + // chunkSize: sizeToBytes(size), |
| 51 | + poolSize: thread |
| 52 | + }) |
| 53 | + ); |
| 54 | + } |
41 | 55 | } catch (error) {
|
42 |
| - fastify.log.error(error); |
| 56 | + // fastify.log.error(error); |
| 57 | + fastify.log.error(error.message); |
43 | 58 | reply.code(500).send({error: error.message});
|
44 | 59 | }
|
45 | 60 | });
|
46 | 61 |
|
47 | 62 | done();
|
48 | 63 | };
|
49 | 64 |
|
50 |
| -// 媒体文件 流式代理,单线程管道方式发送数据,且存在bug,暂不使用 |
51 |
| -function proxyStreamMedia(videoUrl, headers, reply) { |
52 |
| - console.log(`进入了流式代理: ${videoUrl} | headers: ${JSON.stringify(headers)}`); |
53 |
| - |
54 |
| - const protocol = videoUrl.startsWith('https') ? https : http; |
55 |
| - const agent = videoUrl.startsWith('https') ? httpsAgent : httpAgent; |
56 |
| - |
57 |
| - // 发起请求 |
58 |
| - const proxyRequest = protocol.request(videoUrl, {headers, agent}, (videoResponse) => { |
59 |
| - console.log('videoResponse.statusCode:', videoResponse.statusCode); |
60 |
| - console.log('videoResponse.headers:', videoResponse.headers); |
61 |
| - |
62 |
| - if (videoResponse.statusCode === 200 || videoResponse.statusCode === 206) { |
63 |
| - const resp_headers = { |
64 |
| - 'Content-Type': videoResponse.headers['content-type'] || 'application/octet-stream', |
65 |
| - 'Content-Length': videoResponse.headers['content-length'], |
66 |
| - ...(videoResponse.headers['content-range'] ? {'Content-Range': videoResponse.headers['content-range']} : {}), |
67 |
| - }; |
68 |
| - console.log('Response headers:', resp_headers); |
69 |
| - reply.headers(resp_headers).status(videoResponse.statusCode); |
70 |
| - |
71 |
| - // 将响应流直接管道传输给客户端 |
72 |
| - videoResponse.pipe(reply.raw); |
73 |
| - |
74 |
| - videoResponse.on('data', (chunk) => { |
75 |
| - console.log('Data chunk received, size:', chunk.length); |
76 |
| - }); |
77 |
| - |
78 |
| - videoResponse.on('end', () => { |
79 |
| - console.log('Video data transmission complete.'); |
80 |
| - }); |
81 |
| - |
82 |
| - videoResponse.on('error', (err) => { |
83 |
| - console.error('Error during video response:', err.message); |
84 |
| - reply.code(500).send({error: 'Error streaming video', details: err.message}); |
85 |
| - }); |
86 |
| - |
87 |
| - reply.raw.on('finish', () => { |
88 |
| - console.log('Data fully sent to client'); |
89 |
| - }); |
90 |
| - |
91 |
| - // 监听关闭事件,销毁视频响应流 |
92 |
| - reply.raw.on('close', () => { |
93 |
| - console.log('Response stream closed.'); |
94 |
| - videoResponse.destroy(); |
95 |
| - }); |
96 |
| - } else { |
97 |
| - console.error(`Unexpected status code: ${videoResponse.statusCode}`); |
98 |
| - reply.code(videoResponse.statusCode).send({error: 'Failed to fetch video'}); |
99 |
| - } |
100 |
| - }); |
101 |
| - |
102 |
| - // 监听错误事件 |
103 |
| - proxyRequest.on('error', (err) => { |
104 |
| - console.error('Proxy request error:', err.message); |
105 |
| - reply.code(500).send({error: 'Error fetching video', details: err.message}); |
106 |
| - }); |
107 |
| - |
108 |
| - // 必须调用 .end() 才能发送请求 |
109 |
| - proxyRequest.end(); |
110 |
| -} |
111 |
| - |
112 |
| - |
113 | 65 | // Helper function for range-based chunk downloading
|
114 | 66 | async function fetchStream(url, userHeaders, start, end, randUa) {
|
115 | 67 | const headers = keysToLowerCase({
|
@@ -315,7 +267,6 @@ async function proxyStreamMediaMulti(mediaUrl, reqHeaders, request, reply, threa
|
315 | 267 | }
|
316 | 268 | }
|
317 | 269 |
|
318 |
| - |
319 | 270 | // Helper function to convert size string (e.g., '128K', '1M') to bytes
|
320 | 271 | function sizeToBytes(size) {
|
321 | 272 | const sizeMap = {
|
|
0 commit comments