Я создаю веб-интерфейс Jukebox, который будет использоваться несколькими одновременно подключенными клиентами. У них есть только возможность ставить песни в очередь. Если треклист пуст и первая песня стоит в очереди, я бы хотел, чтобы эта песня начала играть.
Сейчас нет способа сделать это. PlaybackController.play()
прервет воспроизводимую в данный момент дорожку, а PlaybackController.resume()
не будет воспроизводить список дорожек, если еще ничего не воспроизводилось.
Очевидно, я могу настроить клиента на что-то вроде:
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();
}
Проблема заключается в том, что если два человека ставят песни в очередь одновременно, они оба могут вернуться в состояние "ОСТАНОВЛЕН", и один человек будет топтать другого. Я хотел бы решить эту проблему, имея что-то встроенное в API, которое позволяет мне как добавить трек, так и объявить, что он должен воспроизводиться, если это единственный трек в списке треков и воспроизведение остановлено.
Я перенес проблему в репозиторий core mopidy, так как это потребует изменений здесь.
Другой способ достичь того, что по сути является настраиваемой атомарной коллекцией
основные операции будут заключаться в предоставлении Frontend, реализующего команду и
убедитесь, что все ваши клиенты используют его. Было бы лучше, если бы у нас был механизм
для расширения веб-сокета.
Вт, 7 апр 2020, 08:55 Штайн Магнус Джодал, [email protected]
написал:
Я перенес проблему в репозиторий core mopidy, так как для этого потребуется
здесь меняется.-
Вы получаете это, потому что подписаны на эту ветку.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/mopidy/mopidy/issues/1897#issuecomment-610236208 или
отказаться от подписки
https://github.com/notifications/unsubscribe-auth/AAHEHKHXVX76W7636PBHZYLRLLMATANCNFSM4MC4SYFQ
.
Помимо условий гонки, заставить это работать надежно с _ single_ клиентом также сложно.
await mopidy.tracklist.add({ tracks: [track] });
await mopidy.playback.play({});
Это не удается, если треклист начинается пустым.
Мой случай использования музыкального автомата прост: люди ставят песни в очередь, а я хочу, чтобы что-то играло всегда. Если список треков был пуст и ничего не воспроизводилось, должна начаться воспроизведение нового трека. Если что-то каким-то образом было приостановлено, они должны остановиться.
Поддерживает ли API это без необходимости делать это, что кажется слишком сложным ?:
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();
}
}
Философия API заключается в том, чтобы каждый метод был сверхточным в том, что он делает, чтобы вы могли использовать их в качестве строительных блоков для построения поведения, подобного моему случаю? Или он должен быть более устойчивым к различным состояниям и очевидным намерениям вызывающего абонента (например, PlaybackController.resume()
продвижение списка треков, если ничего не воспроизводится)
Это не удается, если треклист начинается пустым.
Я должен неправильно понять, потому что это работает для меня, как я и ожидал. Какой бэкэнд вы используете?
При приостановке вызов play
без аргументов должен возобновиться. Учитывая, что, наряду с вышесказанным, разве следующее не делает то же самое, что и ваш фрагмент?
await mopidy.tracklist.add({ tracks: [track] });
const playbackState = await mopidy.playback.getState();
if (playbackState != "playing") {
await mopidy.playback.play({})
}
Имейте в виду, что Core API используется другими интерфейсами, а не только веб-клиентами javascript, поэтому небольшие строительные блоки имеют смысл. Намерение вызывающего может не всегда быть очевидным в других контекстах, поэтому мы обычно не делаем предположений. Для меня идея «возобновления» при остановке не имеет смысла, поскольку возобновлять нечего.
@altano , тебе повезло с моим предложением?
эй @kingosticks , теперь я понимаю, что мог подумать, что этот более простой код не работает из-за несвязанной проблемы, когда GStreamer время от времени просто не воспроизводится после смены трека:
ОШИБКА 2020-04-20 03: 57: 04,106 [1: MainThread] mopidy.audio.gst,
Ошибка GStreamer: не удалось подключиться к серверу,
или
Ошибка GStreamer: не удалось выполнить запись в ресурс.
Я писал об этом на форуме Discourse (я не хотел спамить проблемы с github), но мой пост был помечен как спам и теперь ожидает утверждения.
Как только я проработаю эту проблему, я снова попробую эту более простую логику и посмотрю, сработает ли она.
Самый полезный комментарий
Другой способ достичь того, что по сути является настраиваемой атомарной коллекцией
основные операции будут заключаться в предоставлении Frontend, реализующего команду и
убедитесь, что все ваши клиенты используют его. Было бы лучше, если бы у нас был механизм
для расширения веб-сокета.
Вт, 7 апр 2020, 08:55 Штайн Магнус Джодал, [email protected]
написал: