fix: bilibili音源无法播放的问题 (#1573)

This commit is contained in:
memorydream 2022-04-28 14:45:00 +08:00 committed by GitHub
parent 93ae57adbe
commit c85af59b21
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 107 additions and 43 deletions

View File

@ -88,10 +88,10 @@ function toBuffer(data) {
}
/**
* Get the file URI from bilivideo.
* Get the file base64 data from bilivideo.
*
* @param {string} url The URL to fetch.
* @returns {Promise<string>} The file URI.
* @returns {Promise<string>} The file base64 data.
*/
async function getBiliVideoFile(url) {
const axios = await import('axios').then(m => m.default);
@ -106,7 +106,7 @@ async function getBiliVideoFile(url) {
const buffer = toBuffer(response.data);
const encodedData = buffer.toString('base64');
return `data:application/octet-stream;base64,${encodedData}`;
return encodedData;
}
/**

View File

@ -10,6 +10,7 @@ import { cacheTrackSource, getTrackSource } from '@/utils/db';
import { isCreateMpris, isCreateTray } from '@/utils/platform';
import { Howl, Howler } from 'howler';
import shuffle from 'lodash/shuffle';
import { decode as base642Buffer } from '@/utils/base64';
const PLAY_PAUSE_FADE_DURATION = 200;
@ -329,12 +330,9 @@ export default class {
}
this.setOutputDevice();
}
_getAudioSourceFromCache(id) {
return getTrackSource(id).then(t => {
if (!t) return null;
_getAudioSourceBlobURL(data) {
// Create a new object URL.
const source = URL.createObjectURL(new Blob([t.source]));
const source = URL.createObjectURL(new Blob([data]));
// Clean up the previous object URLs since we've created a new one.
// Revoke object URLs can release the memory taken by a Blob,
@ -348,6 +346,11 @@ export default class {
this.createdBlobRecords = [source];
return source;
}
_getAudioSourceFromCache(id) {
return getTrackSource(id).then(t => {
if (!t) return null;
return this._getAudioSourceBlobURL(t.source);
});
}
_getAudioSourceFromNetease(track) {
@ -416,15 +419,26 @@ export default class {
);
if (store.state.settings.automaticallyCacheSongs && retrieveSongInfo?.url) {
cacheTrackSource(
track,
retrieveSongInfo.url,
128000,
`unm:${retrieveSongInfo.source}`
);
// 对于来自 bilibili 的音源
// retrieveSongInfo.url 是音频数据的base64编码
// 其他音源为实际url
const url =
retrieveSongInfo.source === 'bilibili'
? `data:application/octet-stream;base64,${retrieveSongInfo.url}`
: retrieveSongInfo.url;
cacheTrackSource(track, url, 128000, `unm:${retrieveSongInfo.source}`);
}
return retrieveSongInfo?.url;
if (!retrieveSongInfo) {
return null;
}
if (retrieveSongInfo.source !== 'bilibili') {
return retrieveSongInfo.url;
}
const buffer = base642Buffer(retrieveSongInfo.url);
return this._getAudioSourceBlobURL(buffer);
}
_getAudioSource(track) {
return this._getAudioSourceFromCache(String(track.id))

67
src/utils/base64.js Normal file
View File

@ -0,0 +1,67 @@
// https://github.com/niklasvh/base64-arraybuffer/blob/master/src/index.ts
// Copyright (c) 2012 Niklas von Hertzen Licensed under the MIT license.
const chars =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
// Use a lookup table to find the index.
const lookup = typeof Uint8Array === 'undefined' ? [] : new Uint8Array(256);
for (let i = 0; i < chars.length; i++) {
lookup[chars.charCodeAt(i)] = i;
}
export const encode = arraybuffer => {
let bytes = new Uint8Array(arraybuffer),
i,
len = bytes.length,
base64 = '';
for (i = 0; i < len; i += 3) {
base64 += chars[bytes[i] >> 2];
base64 += chars[((bytes[i] & 3) << 4) | (bytes[i + 1] >> 4)];
base64 += chars[((bytes[i + 1] & 15) << 2) | (bytes[i + 2] >> 6)];
base64 += chars[bytes[i + 2] & 63];
}
if (len % 3 === 2) {
base64 = base64.substring(0, base64.length - 1) + '=';
} else if (len % 3 === 1) {
base64 = base64.substring(0, base64.length - 2) + '==';
}
return base64;
};
export const decode = base64 => {
let bufferLength = base64.length * 0.75,
len = base64.length,
i,
p = 0,
encoded1,
encoded2,
encoded3,
encoded4;
if (base64[base64.length - 1] === '=') {
bufferLength--;
if (base64[base64.length - 2] === '=') {
bufferLength--;
}
}
const arraybuffer = new ArrayBuffer(bufferLength),
bytes = new Uint8Array(arraybuffer);
for (i = 0; i < len; i += 4) {
encoded1 = lookup[base64.charCodeAt(i)];
encoded2 = lookup[base64.charCodeAt(i + 1)];
encoded3 = lookup[base64.charCodeAt(i + 2)];
encoded4 = lookup[base64.charCodeAt(i + 3)];
bytes[p++] = (encoded1 << 2) | (encoded2 >> 4);
bytes[p++] = ((encoded2 & 15) << 4) | (encoded3 >> 2);
bytes[p++] = ((encoded3 & 3) << 6) | (encoded4 & 63);
}
return arraybuffer;
};

View File

@ -301,23 +301,6 @@
</div>
</div>
<div class="item">
<div class="left">
<div class="title"> 请求用代理服务器 (Proxy) </div>
<div class="description">
请求如 YouTube 音源服务时要使用的代理服务器<br />
留空则不进行相关设置
</div>
</div>
<div class="right">
<input
v-model="unmProxyUri"
class="text-input margin-right-0"
placeholder="例 https://192.168.11.45"
/>
</div>
</div>
<div class="item">
<div class="left">
<div class="title"> Joox 引擎的 Cookie </div>