Estou construindo uma IU da web Jukebox que será consumida por vários clientes conectados simultaneamente. Eles só têm a capacidade de enfileirar as músicas. Se a lista de faixas estiver vazia e a primeira música entrar na fila, gostaria que ela começasse a tocar.
No momento, não existe um método para fazer isso. PlaybackController.play()
interromperá a faixa atualmente em reprodução e PlaybackController.resume()
não reproduzirá a lista de faixas se nada estiver sendo reproduzido ainda.
Obviamente, posso preparar o cliente para fazer algo como:
await mopidy.tracklist.add(...);
const playbackState = await mopidy.playback.getState();
if (playbackState === "PAUSED") {
await mopidy.playback.resume();
} else if (playbackState === "STOPPED") {
await mopidy.playback.play();
}
O problema com isso é que, se duas pessoas colocarem músicas na fila ao mesmo tempo, ambas podem voltar ao estado "PARADO" e uma pessoa atropelar a outra. Eu gostaria de resolver isso tendo algo embutido na API que me permite adicionar uma faixa e declarar que ela deve ser reproduzida se for a única faixa na lista de faixas e a reprodução for interrompida.
Transferi o problema para o repositório mopidy principal, pois isso exigiria alterações aqui.
Outra maneira de alcançar o que é essencialmente uma coleção atômica personalizada de
as operações principais seriam fornecer um front-end implementando o comando e
certifique-se de que todos os seus clientes o utilizem. Seria melhor se tivéssemos um mecanismo
para estender o websocket de alguma forma.
Na terça, 7 de abril de 2020, 08:55 Stein Magnus Jodal, [email protected]
escreveu:
Transferi o problema para o repositório mopidy principal, pois isso exigiria
muda aqui.-
Você está recebendo isto porque está inscrito neste tópico.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/mopidy/mopidy/issues/1897#issuecomment-610236208 ou
Cancelar subscrição
https://github.com/notifications/unsubscribe-auth/AAHEHKHXVX76W7636PBHZYLRLLMATANCNFSM4MC4SYFQ
.
Deixando de lado as condições de corrida, fazer com que isso funcione de forma confiável com um cliente _único_ também é difícil.
await mopidy.tracklist.add({ tracks: [track] });
await mopidy.playback.play({});
Isso falha se a tracklist começar vazia.
Meu caso de uso da jukebox é simples: as pessoas colocam músicas na fila e eu quero que alguma coisa esteja sempre tocando. Se a lista de faixas estava vazia e nada estava sendo reproduzido, a nova faixa deve começar a ser reproduzida. Se as coisas foram pausadas de alguma forma, eles deveriam retomar.
A API suporta isso sem ter que fazer isso, o que parece muito complicado ?:
const firstFewTracks = await mopidy.tracklist.slice({ start: 0, end: 3 });
...
const [tlTrack] = await mopidy.tracklist.add({ tracks: [track] });
if (firstFewTracks.length === 0) {
await mopidy.playback.play({ tlid: tlTrack.tlid });
} else {
const playbackState = await mopidy.playback.getState();
if (playbackState === "stopped") {
await mopidy.playback.play({});
} else if (playbackState === "paused") {
await mopidy.playback.resume();
}
}
É a filosofia da API que cada método seja superpreciso exatamente no que faz, para que você possa usá-los como blocos de construção para construir um comportamento como o meu caso? Ou deveria ser mais resiliente aos diferentes estados e intenção óbvia do chamador (por exemplo, PlaybackController.resume()
avançando na lista de faixas se nada estiver tocando)
Isso falha se a tracklist começar vazia.
Devo entender mal, porque isso funciona para mim como eu esperava. Qual back-end você está usando?
Quando em pausa, a chamada de play
sem argumentos deve continuar. Considerando que, junto com o acima, o seguinte não faz a mesma coisa que o seu snippet?
await mopidy.tracklist.add({ tracks: [track] });
const playbackState = await mopidy.playback.getState();
if (playbackState != "playing") {
await mopidy.playback.play({})
}
Lembre-se de que a API principal é consumida por outros front-ends, não apenas por clientes da Web em javascript, portanto, pequenos blocos de construção fazem sentido. A intenção do chamador pode nem sempre ser óbvia em outros contextos, então geralmente não fazemos suposições. Para mim, a ideia de "retomar" quando interrompido não faz sentido, pois não há nada para retomar.
@altano , você teve alguma sorte com minha sugestão?
Ei @kingosticks , agora percebo que devo ter pensado que esse código mais simples não estava funcionando por causa de um problema não relacionado em que o GStreamer esporadicamente falhava em tocar após uma mudança de faixa com:
ERROR 2020-04-20 03: 57: 04.106 [1: MainThread] mopidy.audio.gst,
Erro GStreamer: não foi possível conectar ao servidor,
ou
Erro GStreamer: não foi possível gravar no recurso.
Eu postei sobre isso no fórum do Discurso (não queria enviar spam para questões do github), mas minha postagem foi marcada como spam e agora está aguardando aprovação.
Depois de resolver esse problema, tentarei essa lógica mais simples novamente e verei se funciona.
Comentários muito úteis
Outra maneira de alcançar o que é essencialmente uma coleção atômica personalizada de
as operações principais seriam fornecer um front-end implementando o comando e
certifique-se de que todos os seus clientes o utilizem. Seria melhor se tivéssemos um mecanismo
para estender o websocket de alguma forma.
Na terça, 7 de abril de 2020, 08:55 Stein Magnus Jodal, [email protected]
escreveu: