AI และเอเจนต์23 นาทีในการอ่าน

Spotify บน Yandex Station Lite: Soloist ตัวทางการบนลำโพงที่ได้ root

Spotify Connect บน Yandex Station Lite 1 ผ่าน Soloist ตัวทางการ: ทำไม librespot เล่นไม่ได้ อุปสรรคที่ซ่อนอยู่สามอย่าง และอลิซพูดทับเสียงเพลงได้อย่างไร

Spotify บน Yandex Station Lite: Soloist ตัวทางการบนลำโพงที่ได้ root
สารบัญ

Spotify บน Yandex Station Lite เล่นได้แล้ว ลำโพงขึ้นในรายชื่ออุปกรณ์ Spotify Connect บนมือถือ เพลงดังออกจากลำโพงของมันเอง ส่วนอลิซก็ตอบทับเสียงเพลงได้สบาย ๆ โดยไม่เงียบไป คำสั่ง “Alisa, vklyuchi spotifay” (“อลิซ เปิด Spotify”) ก็ใช้ได้ (Yandex Station Lite คือลำโพงอัจฉริยะของ Yandex บริษัทเทคโนโลยีรายใหญ่ของรัสเซีย ขายหลัก ๆ ในรัสเซียและประเทศกลุ่ม CIS ส่วนอลิซ (Alice) คือผู้ช่วยเสียงในตัวลำโพงที่ฟังและพูดภาษารัสเซีย คำสั่งเสียงในบทความนี้จึงเป็นภาษารัสเซีย เราเขียนเป็นตัวอักษรละตินพร้อมคำแปล) ทั้งหมดนี้ทำงานบนไคลเอนต์ทางการของ Spotify ชื่อ Soloist ซึ่งไม่ได้ออกแบบมาสำหรับลำโพงตัวนี้ ทั้งเรื่องไลบรารีและเรื่องเสียง กว่าจะให้มันรันได้ เราต้องประกอบ Debian ขนาดจิ๋วให้มันในโฟลเดอร์แยก และฝ่าอุปสรรคสามอย่าง ซึ่งแต่ละอย่างตอนแรกดูเหมือนเป็นปัญหาอื่น

บอกสถานะก่อนเลย ระบบเปิดอัตโนมัติพร้อมแล้วและผ่านการทดสอบรีบูตสองครั้ง: ลำโพงกลับเข้า Wi-Fi บ้านเอง Spotify ขึ้นมาเองโดยไม่ต้องแตะอะไร แต่ไม่ได้ขึ้นทันที หลังเปิดเครื่องต้องรอไม่กี่นาที เพราะการล็อกอินบัญชีครั้งแรกมักล้มเหลว และสคริปต์ supervisor จะลองใหม่เอง ภาระที่เหลืออยู่อย่างเดียวคือต้องเปลี่ยนตัวไคลเอนต์ทุก 90 วัน

ทำไมต้องมี Spotify บน Yandex Station ในเมื่อมี Yandex Music อยู่แล้ว

นี่คือตอนที่สองของเรื่องลำโพงตัวเดียวกัน ในตอนแรก เราได้ root บน Station Lite รุ่นแรก และสอนให้มันตอบด้วยหัวสมองของ AI เอเจนต์ของเรา Mia เมื่อได้ยินประโยค “Alisa, sprosi neyroset” (“อลิซ ถามนิวรัลเน็ตเวิร์กหน่อย”) ทุกอย่างจบตอนราวตีหนึ่ง และดูเหมือนจะปิดโน้ตบุ๊กได้แล้ว

แต่ปิดไม่ลง ในเมื่อตอนนี้ลำโพงเป็นของเราเต็มตัวแล้ว ก็อยากให้มันเล่นได้มากกว่า Yandex Music สิ่งที่ต้องการคือ Spotify Connect: เปิด Spotify บนมือถือ เลือกลำโพงในรายชื่ออุปกรณ์ แล้วเพลงก็ออกจากลำโพง ส่วนมือถือทำหน้าที่เป็นรีโมต Station ไม่รองรับ Spotify Connect มาตั้งแต่โรงงาน และก็ไม่ได้ถูกออกแบบมาให้รองรับด้วย

คนไข้คนเดิม: Yandex Station Lite รุ่น YNDX-00025 ข้างในเป็นโปรเซสเซอร์ Cortex-A53 แรม 244 MB และ Linux บนเคอร์เนล 4.9 เคอร์เนลเป็น 64 บิต แต่โปรแกรมทั้งหมดเป็น 32 บิต ไลบรารีระบบ glibc เป็นเวอร์ชัน 2.30 ตัวเลขเหล่านี้จะโผล่มาอีกหลายครั้ง เพราะทุกอย่างหลังจากนี้ไปติดอยู่ที่มันนี่แหละ

ลองครั้งแรก: librespot ที่ข้ามเพลงไปเรื่อย ๆ

คอมมูนิตี้แก้โจทย์นี้มานานแล้วด้วย librespot ซึ่งเป็น Spotify Connect แบบโอเพนซอร์ส สำหรับ Station Lite และ Mini มีตัวติดตั้งสำเร็จรูปอยู่แล้ว เราเลยเริ่มจากตัวนั้น

ตอนแรกตัวติดตั้งไม่ยอมทำงาน: เฟิร์มแวร์ของเราไม่มีไดเรกทอรี /usr/local/bin ที่มันจะวางคำสั่งของตัวเองไว้ เราสร้างไดเรกทอรีให้ หลังจากนั้นทุกอย่างก็ราบรื่น ลำโพงขึ้นใน Spotify แอปเลือกมันได้ แล้วเรื่องแปลกก็เริ่มขึ้น: เพลงถูกข้ามไปทีละเพลง ไม่มีเพลงไหนดังออกมาเลย ในล็อกมีบรรทัดเดิมซ้ำทุกเพลง: Unable to load key ดึงคีย์ถอดรหัสไม่ได้ ข้ามเพลงไป

เรื่องยังไปไม่ถึงตัวลำโพง ดอกลำโพง หรือเสียงเลยด้วยซ้ำ: ไม่มีคีย์ถอดรหัส เพลงก็เล่นไม่ได้ สาเหตุไม่ได้อยู่ที่เรา นักพัฒนา librespot เขียนไว้ใน issue #1649 เมื่อ 7 พฤศจิกายน 2569 ว่าการเล่นเพลงพังสำหรับบัญชีที่สร้างหลังช่วงเวลาหนึ่ง ราวปี 2567–2568 เขาบอกว่าปัญหานี้มีในทุกเวอร์ชันของ librespot และไม่มีทางเลี่ยง เพราะไคลเอนต์ทางการได้คีย์ผ่านอีกวิธีหนึ่งที่มีการป้องกัน

ดูเหมือนบัญชีของเราจะเป็นหนึ่งในนั้น เราถอด librespot ออกจากลำโพงทั้งหมด รวมถึงไดเรกทอรีที่สร้างไว้ให้ตัวติดตั้งด้วย

Soloist: ไคลเอนต์ทางการที่ลงตรงนี้ไม่ได้

ตั้งแต่สิงหาคม 2569 Spotify มีคำตอบของตัวเองให้โจทย์นี้ Spotify Soloist คือไคลเอนต์ Spotify Connect ทางการแบบ “headless” สำหรับ Linux: ไม่มีหน้าจอ ไม่มีอินเทอร์เฟซ มีแค่อุปกรณ์ในรายชื่อของแอป การรันต้องใช้ API key ซึ่งออกได้จากบัญชี Premium บิลด์มีอายุจำกัด: ของเราแจ้งตอนเริ่มทำงานว่าจะหมดอายุในอีก 88 วัน ไตรมาสละครั้งต้องเปลี่ยนโปรแกรมเป็นตัวใหม่

มีบิลด์สำหรับ ARM 32 บิตด้วย ซึ่งก็คือโปรเซสเซอร์ของเรา เราดาวน์โหลดจากเซิร์ฟเวอร์ทางการของ Spotify แล้วพบว่ามันลงบนลำโพงตรง ๆ ไม่ได้ มีสองเรื่องที่ขวางอยู่

เรื่องแรกคือไลบรารีระบบ Soloist ถูกคอมไพล์มาสำหรับ glibc 2.38 แต่บนลำโพงเป็น 2.30 เหมือนแอปที่ต้องการ Android เวอร์ชันใหม่: บนเวอร์ชันเก่ามันเปิดไม่ขึ้นเลย

เรื่องที่สองคือเสียง บน Linux Soloist ส่งเสียงออกได้ผ่านเซิร์ฟเวอร์เสียง PulseAudio หรือ PipeWire เท่านั้น บนลำโพงไม่มีทั้งสองตัว มีแต่ ALSA เปล่า ๆ ซึ่งเป็นชั้นเสียงล่างสุดของ Linux และเป็นทางที่อลิซใช้พูด

อัปเดตระบบของลำโพงไม่ได้ และก็ไม่จำเป็นด้วย: เฟิร์มแวร์ของ Yandex คุมทุกอย่างที่เหลือ รวมถึงอลิซและบริดจ์ของ Mia เราเลยตัดสินใจสร้างโลกจิ๋วแยกไว้ข้าง ๆ

Debian ของเราเองในโฟลเดอร์แยก

ไอเดียง่าย ๆ แม้บนแรม 244 MB จะดูบ้าบิ่นไปหน่อย เราหยิบ glibc 2.41 ตัวใหม่ PulseAudio 17 และทุกอย่างที่มันต้องใช้จาก Debian 13 (trixie) สำหรับ ARM 32 บิต แล้ววางไว้ในโฟลเดอร์แยกบนลำโพง Soloist ไม่ได้รันตรง ๆ แต่รันผ่าน loader จากโฟลเดอร์นี้ โดยบอก path ไปยังไลบรารีของเรา

จะเลือกทางลัดก็ได้ คือใส่ path ของไลบรารีใหม่ในตัวแปร LD_LIBRARY_PATH ของบริการระบบ แต่แบบนั้นโปรแกรมของ Yandex ที่คอมไพล์มากับ glibc เก่าก็จะหยิบไปใช้ด้วย และลำโพงน่าจะหยุดทำงานทั้งเครื่อง เราจึงไม่เปลี่ยนไลบรารีระบบของเฟิร์มแวร์: ไลบรารีใหม่วางแยกไว้ และมีแค่ Soloist กับ PulseAudio ที่ใช้

ประกอบชุดบนโน้ตบุ๊ก ดาวน์โหลดแพ็กเกจ Debian 129 แพ็กเกจ และตรวจแต่ละตัวกับ checksum จากดัชนีทางการ จากรายการ dependency เราคัดไลบรารีมาพอดี 38 ตัว ไม่มี locale ไม่มีเอกสาร ไม่มีของเกินอื่น ๆ ชุดทั้งหมดได้ 41 MB จากพื้นที่ว่าง 57 MB บนพาร์ทิชัน แน่น แต่ใส่ได้

ภายใต้ loader ของเรา Soloist ตอบกลับเป็นเวอร์ชัน 1.3.10 ส่วน PulseAudio เป็นเวอร์ชัน 17.0 ผ่านขั้นแรกแล้ว จากนี้ไปคืออุปสรรคที่เราไม่ได้คาดไว้

กำแพงแรก: เสียงที่เปิดไม่ขึ้น

PulseAudio จาก Debian ควรส่งเสียงออก ALSA ของลำโพงได้เอง แต่มันกลับล่มตั้งแต่เรียกการ์ดเสียงครั้งแรก พร้อมข้อผิดพลาด SNDRV_PCM_IOCTL_SYNC_PTR failed (-25)

คำตอบอยู่ที่อายุของเคอร์เนล บิลด์ 32 บิตรุ่นใหม่ของ Debian เปลี่ยนไปใช้เวลาแบบ 64 บิตแล้ว เพื่อป้องกัน “ปัญหาปี 2038” ที่ตัวนับวินาทีแบบ 32 บิตจะล้น ไลบรารีเสียงจาก Debian ของเราขอให้เคอร์เนลทำงานเดิมด้วยคำสั่งรูปแบบใหม่ที่ใช้เวลาแบบ 64 บิต แต่เคอร์เนล 4.9 ไม่รู้จักรูปแบบนี้ และตอบกลับว่า “ไม่เข้าใจ” อัปเดตเคอร์เนลก็ไม่ได้ เพราะมันเป็นส่วนหนึ่งของเฟิร์มแวร์

ทางออกคือเลี่ยงอ้อม PulseAudio ไม่เข้าไปที่การ์ดเสียงเองอีกต่อไป แต่เขียนเสียงที่พร้อมแล้วลงใน named pipe (FIFO) ซึ่งเหมือนท่อเชื่อมระหว่างโปรแกรม อีกฝั่งของท่อคือ aplay เครื่องเล่นดั้งเดิมของลำโพง ซึ่งใช้ไลบรารีระบบตัวเก่าที่เข้ากับเคอร์เนลได้ดี แบบนี้เสียงทั้งสองแหล่ง ทั้งเพลงและอลิซ จะเข้า mixer dmix ตัวเดียวกัน ทีหลังเราตรวจแล้วว่าได้ยินอลิซทับเพลง แต่ก่อนจะถึงตรงนั้นยังอีกไกล และเวอร์ชันแรกของวิธีนี้จบลงด้วยเสียงค้างสำหรับทุกโปรแกรม

กำแพงที่สอง: ลำโพงตะโกนผิดเครือข่าย

ต่อไปต้องใช้คีย์ของ Soloist ผมออกคีย์บนเว็บไซต์ Spotify for Developers แล้วเก็บไว้ในไฟล์ จากนั้นคีย์ก็ถูกส่งไปที่ลำโพงโดยให้สิทธิ์อ่านได้เฉพาะ root Soloist เริ่มทำงานและรายงานว่าประกาศตัวในเครือข่ายแล้ว แต่มือถือมองไม่เห็นลำโพง

อุปกรณ์ Spotify Connect หากันเจอผ่าน mDNS: มีคนถามว่า “ใครในนี้เล่นเพลงได้บ้าง” แล้วอุปกรณ์ก็ตอบ การตรวจจากโน้ตบุ๊กพบว่า Soloist ตอบคำถามเรื่องที่อยู่ได้แบบหนึ่ง แต่คำถามแบบกลุ่ม (multicast) ตามปกติในเครือข่ายบ้านกลับไม่ได้รับคำตอบ ปรากฏว่า Station มีอินเทอร์เฟซ Wi-Fi Direct สำหรับใช้ภายในชื่อ p2p0 พร้อมที่อยู่ภายในแบบ 169.254.x.x และ Soloist เห็นที่อยู่นี้เป็นอันดับแรกในรายการ ดูเหมือนเพราะเหตุนี้คำตอบจึงไปไม่ถึงเครือข่ายบ้าน

เราลบที่อยู่ออกจาก p2p0 รีสตาร์ต Soloist แล้วมือถือก็เคาะประตูหาลำโพงทันที นี่เป็นมาตรการชั่วคราว: หลังรีบูต ที่อยู่จะกลับมา วิธีถาวรยังต้องเลือกกันอีกที เพราะเรายังไม่รู้ว่า Yandex เองใช้อินเทอร์เฟซนี้ทำอะไร

กำแพงที่สาม: เห็นลำโพง แต่เชื่อมต่อไม่ได้

ลำโพงขึ้นใน Spotify บนมือถือแล้ว จากนั้นก็ไม่มีอะไรเกิดขึ้น: มือถือพยายามเชื่อมต่อแต่ทำไม่ได้ เว็บเซิร์ฟเวอร์ในตัวของ Soloist ซึ่งเป็นทางที่มือถือส่งเซสชันมา รับการเชื่อมต่อเข้าคิวแต่ไม่ประมวลผลเลยสักอัน ส่วนเธรดหลักของโปรแกรมก็ยุ่งตลอดเวลาและเผา CPU และเผาเฉพาะใน kernel mode เหมือนกำลังขออะไรบางอย่างจากระบบไม่หยุดโดยไม่เคยได้คำตอบ

คำใบ้มาจาก system log: ทุกรอบเคอร์เนลบ่นว่าเธรด SoloistRunner M ใช้ “คำสั่ง CP15 barrier ที่เลิกใช้แล้ว” เราแกะรหัสเครื่องที่ตำแหน่งนั้นและเจอลูปที่พยายามเปลี่ยนค่าหนึ่งไบต์แบบ atomic ในโปรเซสเซอร์ ARM งานนี้ทำด้วยคำสั่งคู่หนึ่ง: คำสั่งแรกติดเครื่องหมายที่มองไม่เห็นไว้บนช่องหน่วยความจำว่า “ฉันกำลังอ่านช่องนี้” คำสั่งที่สองเขียนค่าใหม่ ก็ต่อเมื่อเครื่องหมายยังอยู่ ระหว่างสองคำสั่งนี้ในโค้ดของ Soloist มี memory barrier ที่เขียนแบบเก่า สไตล์โปรเซสเซอร์ ARMv7 32 บิต

ในการตั้งค่าเดิมของลำโพง เคอร์เนลไม่ปล่อย barrier แบบนี้ให้โปรเซสเซอร์ แต่ดักไว้และทำแทนเอง ดูเหมือนว่าตอนที่ดักนี้เองเครื่องหมายจะถูกล้าง: กลายเป็นวงจรปิด โปรแกรมติดเครื่องหมาย barrier ลบมันทิ้ง การเขียนถูกปฏิเสธ โปรแกรมเริ่มใหม่ ไม่มีที่สิ้นสุด

เราทดสอบด้วยการเปลี่ยนโหมด: echo 2 > /proc/sys/abi/cp15_barrier บรรทัดนี้บอกเคอร์เนลว่าไม่ต้องดัก barrier แบบเก่าอีกแล้ว ให้โปรเซสเซอร์ทำเอง ซึ่ง Cortex-A53 ทำได้ หลังรีสตาร์ต Soloist เธรดหลักก็หลับรออย่างที่ควรเป็นในที่สุด และเว็บเซิร์ฟเวอร์ของลำโพงเริ่มตอบคำขอใน 40–130 มิลลิวินาที การตั้งค่านี้มีผลจนกว่าจะรีบูต ในสคริปต์เปิดอัตโนมัติจึงวางไว้เป็นหนึ่งในขั้นแรก ๆ

ข้อแม้สำคัญ: อาการค้างหายไปและการตอบกลับก็มา อันนี้เราเห็นกับตา แต่กลไกเรื่องเครื่องหมายที่ถูกล้างยังเป็นสมมติฐานของเรา และเราก็เขียนไว้แบบนั้นตรง ๆ ตอนส่งสิ่งที่เจอไปให้ Spotify

จากอาการ “เห็นลำโพงแต่เชื่อมต่อไม่ได้” แทบเป็นไปไม่ได้ที่จะหาต้นเหตุนี้เจอ นี่คือกรณีที่ผู้ต้องสงสัยหน้าเดิม ๆ อย่างเครือข่าย คีย์ หรือ Spotify ไม่เกี่ยวเลย

หลังกำแพงที่สาม ในล็อกของ Soloist ก็มีบรรทัดที่เราทำทั้งหมดนี้เพื่อมัน: มือถือเข้ามาแล้ว ได้คีย์แล้ว กำลังเล่น “La clé des champs” ของวง NTO ส่วนของ Spotify ทำงานแล้ว คีย์ถอดรหัสที่ librespot ไม่เคยได้รับบนบัญชีนี้ ไคลเอนต์ทางการได้มาโดยไม่มีปัญหา

แต่จากลำโพงกลับไม่มีเสียงอะไรเลย

เราทำลำโพงเสียงหายได้อย่างไร

ตรงนี้เป็นช่วงที่ไม่น่าเล่าของเรื่อง แต่ถ้าไม่เล่า เรื่องนี้ก็จะไม่ซื่อตรง

วิธีจัดการเสียงแบบแรกง่ายที่สุด: aplay อ่านท่อจาก PulseAudio ตลอดเวลา ไม่ว่าจะมีเพลงหรือไม่ ครั้งแรกมันตายเพราะเราปิดเซสชันดีบัก: เมื่อรันจากบรรทัดคำสั่ง โพรเซสก็ตายตามเซสชันไปด้วย ต่อมาปรากฏว่าเสียงไม่ออกแล้วสำหรับทุกโปรแกรม เอาต์พุตรวมของการ์ดเสียงค้างอยู่ในสถานะ “เตรียมแล้วแต่ยังไม่เริ่ม” และพร้อมกับเพลง อลิซก็เงียบไปด้วย คืนเสียงโดยไม่รีบูตไม่ได้

รีบูตคืนเสียงกลับมา และพราก Wi-Fi บ้านไปทันที ตอนบูต Yandex เขียนการตั้งค่าเครือข่ายใหม่จากฐานข้อมูลของตัวเอง และเครือข่ายบ้านที่เราเพิ่มเองด้วยมือไม่ได้อยู่ในฐานข้อมูลนั้น เครือข่ายบ้านหายไปจากรายการเลย แต่ฮอตสปอตจากโน้ตบุ๊กที่ลำโพงเคยใช้ตอนได้ root ยังอยู่ ไม่มีอินเทอร์เน็ต อลิซก็พูดแต่ว่า “ไม่มีอินเทอร์เน็ต” เราหาลำโพงเจอด้วยการเปิดฮอตสปอตตัวนั้น และล็อกเครือข่ายบ้านไว้ด้วยสคริปต์เล็ก ๆ อีกตัว: นาทีละครั้งมันจะเช็กรายการเครือข่าย ถ้าไม่มีเครือข่ายบ้าน ก็เพิ่มกลับเข้าไป หลังรีบูตขั้นนี้ใช้เวลาราวหนึ่งนาทีครึ่ง ระหว่างนั้นอลิซก็บอกตามจริงว่าไม่มีอินเทอร์เน็ต

พูดตรง ๆ เรายังไม่รู้แน่ว่าทำไมเสียงถึงค้าง คำอธิบายแรกที่ว่า “aplay ของเรากลายเป็นตัวหลักของ mixer แล้วตายไป ทิ้ง mixer ไว้โดยไม่มีเจ้าของ” ไม่ได้รับการยืนยัน: ตามซอร์สโค้ดของไลบรารีเสียง โหมดแบบนี้ไม่มีบนเคอร์เนลนี้ สมมติฐานใช้งานที่เราได้มาร่วมกับความเห็นที่สองจาก Codex คือ โพรเซสตายกลางการกู้คืนหลังเกิดข้อผิดพลาด ตรงระหว่าง “เตรียม” กับ “เริ่ม” พอดี และเอาต์พุตรวมก็ค้างอยู่ในสถานะเตรียมแล้ว นี่เป็นสมมติฐาน ไม่ใช่ข้อพิสูจน์

ในเมื่อยังหาสาเหตุไม่ได้ จากนี้เราจึงเดินแบบระวัง: โพรเซสแปลกปลอมไม่ควรถือเอาต์พุตเสียงรวมไว้นานเกินจำเป็น และไม่ควรตายกลางคัน

ยามที่ปล่อยเสียงเฉพาะตอนเพลงเล่น

วิธีใหม่อาศัยสคริปต์ยามตัวเล็ก ๆ มันอ่านล็อกของ Soloist ทันทีที่มีคำว่า “กำลังเล่น” ยามก็เปิด aplay เมื่อมี “หยุดชั่วคราว” หรือมือถือสลับไปอุปกรณ์อื่น ยามจะรอห้าวินาที แล้วหยุดเครื่องเล่นอย่างสุภาพด้วยสัญญาณที่ทำให้มันปิดการ์ดเสียงเอง ไม่มีการฆ่าโพรเซสแบบบังคับ

เราทดสอบตามขั้นตอน โดยเขียนเกณฑ์หยุดไว้ล่วงหน้า: ถ้าอลิซเงียบหรือเอาต์พุตเสียงหยุดเดิน ให้เก็บข้อมูลวินิจฉัยก่อน แล้วค่อยกู้ลำโพง ผมนั่งฟัง เริ่มด้วยความเงียบหนึ่งวินาทีผ่าน aplay ของระบบ: เอาต์พุตเริ่มและปิดได้เรียบร้อย ต่อด้วยเพลงเบา ๆ และอลิซพูดทับ ได้ยินทั้งคู่ กดหยุดชั่วคราว: เครื่องเล่นหยุด เอาต์พุตปิด อลิซพูดอยู่คนเดียว กด play อีกครั้ง: เพลงกลับมา ตลอดการทดสอบเสียงไม่ค้างเลยสักครั้ง

ระหว่างทางมีกับดักอีกอัน Soloist แคชเพลง และฟังไปห้านาที แคชก็โตถึง 15 MB บนพาร์ทิชันที่แคชอยู่ เหลือพื้นที่ 13.8 MB และที่เดียวกันนั้นยังเป็นที่เก็บข้อมูลของ Yandex การตั้งค่า Wi-Fi และบริดจ์ของ Mia อีกนิดเดียว ลำโพงก็จะชนดิสก์เต็มในจุดที่แย่ที่สุด เราย้ายแคชไปไว้ในแรมพร้อมเพดานตายตัว 12 MB และทดสอบแยกต่างหากว่าจะเกิดอะไรขึ้นเมื่อ 12 MB นั้นก็เต็ม การทดสอบใช้เวลาราวสิบนาที: แคชเต็มเกือบหมด หลังจากนั้นเปลี่ยนไปสองเพลง และไม่มีข้อผิดพลาดในล็อกเลยสักบรรทัด

Spotify ใช้หน่วยความจำบน Yandex Station Lite เท่าไร

ค่าที่วัดได้ระหว่างเล่นเพลง: Soloist ใช้หน่วยความจำราว 50 MB, PulseAudio 3.5 MB, aplay 1.7 MB ระบบยังเหลือหน่วยความจำให้ใช้ 68–70 MB จาก 244 MB และเมื่อแคชในแรมเต็มจะเหลือราว 60 MB เกณฑ์ที่เราตกลงกันว่าถ้าต่ำกว่านี้จะปิดทุกอย่างคือ 40 MB Soloist ใช้ CPU ราว 4% บริดจ์ของ Mia ตอบได้ปกติตลอดเวลา

สำหรับลำโพงที่ออกแบบมาให้รันแค่อลิซ ในการทดสอบสั้น ๆ หน่วยความจำที่เหลือยังสูงกว่าเกณฑ์ของเรา แต่เมื่อเปิดเพลงหลายชั่วโมงจะเป็นอย่างไร เรายังไม่รู้: ยังไม่ได้ทดสอบนาน ๆ

เปิดอัตโนมัติ: ลำโพงเปิด Spotify เอง

ขั้นสุดท้ายคือทำให้ทุกอย่างกลับมาเองหลังถอดปลั๊ก โดยไม่ต้องใช้โน้ตบุ๊ก สคริปต์ supervisor ทำตามลำดับ: รอเครือข่าย ลบที่อยู่ออกจาก p2p0 สลับโหมด barrier สร้างแคชในแรม จากนั้นเปิดเสียง Soloist และยาม ถ้าไคลเอนต์ล่ม supervisor จะเปิดมันขึ้นมาใหม่ ถ้าบิลด์หมดอายุแล้วจะไม่ยุ่ง เพราะรีสตาร์ตไปเรื่อย ๆ ก็ไม่มีประโยชน์

ทดสอบด้วยการรีบูตสองครั้ง ลำโพงกลับเข้า Wi-Fi บ้านเอง Spotify ขึ้นในรายชื่ออุปกรณ์ บริดจ์ของ Mia และการระงับอัปเดตเฟิร์มแวร์ไม่ได้รับผลกระทบ

มีรายละเอียดหนึ่งที่ต้องบอกตรง ๆ: การล็อกอินบัญชี Spotify ครั้งแรกหลังบูตมักไม่ผ่าน ครั้งแรกสาเหตุชัดเจน นาฬิกาของลำโพงยังอยู่ที่ปี 2513 (ค.ศ. 1970) และด้วยเวลาแบบนั้นตรวจใบรับรองไม่ได้ ครั้งที่สอง เครือข่าย นาฬิกา และ DNS เรียบร้อยแล้ว แต่ล็อกอินก็ยังล้มเหลว และเราไม่รู้ว่าทำไม supervisor จับได้เองและลองใหม่ ในการรีบูตครั้งที่สอง Spotify จึงพร้อมใช้ราวสามถึงสี่นาทีหลังเปิดเครื่อง ทีหลังเราทำให้การลองใหม่เร็วขึ้น ผลเป็นอย่างไรอยู่ด้านล่าง ในส่วนเรื่องตัวติดตั้ง

สั่งด้วยเสียง: “Alisa, vklyuchi spotifay”

มือถือเป็นรีโมตก็ดี แต่ลำโพงที่มีอลิซแล้วสั่งด้วยเสียงไม่ได้ ยังดูไม่เสร็จ ตอนนี้ทำได้แล้ว มีสามประโยค: “Alisa, vklyuchi spotifay” (“อลิซ เปิด Spotify”) เล่นต่อจากเพลงที่เล่นล่าสุด “Alisa, pauza v spotifay” (“อลิซ หยุด Spotify ชั่วคราว”) หยุดเพลงชั่วคราว “Alisa, sleduyushchiy trek v spotifay” (“อลิซ เพลงถัดไปใน Spotify”) เปลี่ยนเพลง ถ้าไม่มีคำว่า “spotifay” ทุกอย่างยังไปที่ Yandex เหมือนเดิม: “Alisa, pauza” จะหยุด Yandex Music ไม่ใช่ Spotify

กลไกนี้ทำงานบนบริดจ์จากตอนแรก กฎใน Quasar Bridge จะมองหาคำว่า “spotif” ในประโยคที่รู้จำได้ (ในกฎจริงคือต้นคำ Spotify ที่เขียนด้วยอักษรรัสเซีย เพราะระบบรู้จำเสียงถอดคำออกมาเป็นภาษารัสเซีย) และส่งประโยคนั้นไปให้ Mia เวอร์ชันเสียงแทน Yandex แล้ว Mia ก็ยืนยันสั้น ๆ ออกเสียง ในเวลาเดียวกัน ตัวสังเกตการณ์เล็ก ๆ บนลำโพงก็เห็นในล็อกของบริดจ์ว่าคำขอส่งไปหา Mia แล้ว และสั่ง Soloist: เล่น หยุดชั่วคราว หรือเพลงถัดไป ล็อกประโยคอยู่แค่ในแรมของลำโพง และตัวสังเกตการณ์เองก็ไม่ได้บันทึกข้อความประโยคไว้ที่ไหนเลย

ทำไมต้องอ้อมแบบนี้ ไม่ใช้เครื่องมือของเอเจนต์ตรง ๆ: เอเจนต์ของเราบนเซิร์ฟเวอร์รันเครื่องมือที่ฝั่งตัวเอง และไม่ส่งการเรียกกลับมาที่ลำโพง มันเอื้อมไม่ถึง Soloist แต่ตัวสังเกตการณ์ที่อยู่บนลำโพงเอื้อมถึง

ทดสอบด้วยเสียงแล้ว ข้อจำกัดมีข้อเดียวแต่เห็นได้ชัด: ขอศิลปินหรือเพลงเจาะจงไม่ได้ Soloist ไม่มีการค้นหา ถ้าจะค้นต้องใช้ Web API ของ Spotify แยกต่างหาก การสั่งด้วยเสียงจะรอดหลังรีบูตหรือไม่ เรายังไม่ได้ทดสอบแยก แต่ตัวสังเกตการณ์เริ่มพร้อม Soloist ก็น่าจะรอด

ระดับเสียง: เพลงตามอลิซ

Soloist มีระดับเสียงของตัวเอง ค่าเริ่มต้น 40 จาก 100 เพลงจึงเริ่มที่ครึ่งเดียว ส่วนปุ่มบนลำโพงและ “Alisa, gromche” (“อลิซ ดังขึ้น”) ก็เอื้อมไปไม่ถึง อลิซเก็บระดับเสียงของตัวเองบนสเกล 0 ถึง 20 ในไฟล์แยก และใช้กับเครื่องเล่นของตัวเองเท่านั้น โดยไม่แตะตัวปรับเสียงรวม Soloist จึงไม่รู้ว่าระดับเสียงเปลี่ยน: เสียงอลิซเบาลงหรือดังขึ้น แต่เพลงยังเล่นเท่าเดิม

ในชุดจึงมีสคริปต์ซิงก์เล็ก ๆ วินาทีละครั้งมันจะอ่านระดับเสียงของอลิซแล้วส่งให้ Soloist โดยแปลงสเกล: 15 จาก 20 ของอลิซกลายเป็น 75 จาก 100 ของ Spotify โหมดเงียบของอลิซก็ปิดเสียงเพลงด้วย Soloist เริ่มทำงานด้วยระดับเสียงของอลิซทันที ไม่ใช่ 40 ของตัวเอง ตัวปรับเสียงในแอป Spotify ก็ใช้ได้ แต่แค่จนกว่าอลิซจะเปลี่ยนระดับเสียงครั้งถัดไป ด้วยปุ่มหรือด้วยเสียง ใครไม่ต้องการซิงก์ ปิดได้ด้วยบรรทัดเดียวในไฟล์ตั้งค่า

ทดสอบด้วยเทสต์สามตัว ซึ่งแต่ละตัวจะล้มถ้าไม่มีสคริปต์นี้ และทดสอบบนลำโพงจริง: Soloist เริ่มที่ 75 เมื่ออลิซอยู่ที่ 15 หลังรีบูตบริการขึ้นมาเอง และในล็อกของลำโพงเห็นว่าอลิซที่ 17 กลายเป็น 85 ใน Spotify ปุ่มและเสียง ผมทดสอบเอง: เพลงเปลี่ยนตามอลิซ

ตัวติดตั้ง: เพื่อให้ทำซ้ำได้

ทุกอย่างข้างบนทำด้วยมือ ทีละคำสั่ง ใช้ได้ แต่ทำซ้ำตามคำอธิบายไม่ได้: ความเห็นที่สองจาก Codex บอกตรง ๆ ว่าสูตรแบบนี้ทำซ้ำไม่ได้ และยังเจอข้อบกพร่องในสคริปต์ด้วย เราจึงเปลี่ยนงานมือให้เป็นตัวติดตั้ง

ตัวติดตั้งมีสองส่วน ส่วนแรกคือตัวประกอบชุดบนคอมพิวเตอร์: คำสั่ง Python คำสั่งเดียว ไม่มี dependency ภายนอก ทำงานบน Windows, Linux และ macOS ไม่ต้องใช้ Docker มันดาวน์โหลดดัชนีของ Debian 13 คำนวณ dependency เอง ดาวน์โหลดแพ็กเกจราว 130 ตัวและตรวจแต่ละตัวด้วย checksum คัดไลบรารีที่ต้องใช้ 36 ตัว และดึง Soloist จากเซิร์ฟเวอร์ของ Spotify ชุดขนาด 39.6 MB ประกอบเสร็จในราวหนึ่งนาที ถ้าขาดไลบรารีตัวไหน ตัวประกอบจะหยุดพร้อมข้อผิดพลาด แทนที่จะประกอบชุดเสีย ๆ ออกมาเงียบ ๆ ตัว Soloist เองไม่ได้อยู่ในตัวติดตั้ง: Spotify ห้ามแจกจ่ายไฟล์บีบอัดและไบนารีของมันไว้ชัดเจน ตัวประกอบจึงดาวน์โหลดให้ผู้ใช้แต่ละคนเอง

ส่วนที่สองติดตั้งชุดลงลำโพงผ่าน ADB ด้วยคำสั่งเดียวเหมือนกัน พื้นที่บนลำโพงพอดีเป๊ะ ว่างราว 28 MB สำหรับชุดขนาด 40 MB ไฟล์ที่ไม่เปลี่ยนจึงไม่คัดลอกใหม่ แต่เชื่อมด้วย hard link ถ้าหลังหยุดเวอร์ชันเก่าแล้วมีอะไรผิดพลาด ตัวติดตั้งจะคืนทุกอย่างกลับเหมือนเดิม และถ้าคืนไม่ได้ ก็บอกตรง ๆ แทนที่จะรายงานว่าสำเร็จ บนลำโพงของเรา จาก 51 ไฟล์ มี 39 ไฟล์ที่ตรงกันทุกไบต์ ต้องคัดลอกแค่ 12 ไฟล์ รวมแค่ 208 KB หลังรีบูต Spotify ล็อกอินได้ตั้งแต่ครั้งแรก ราวสองนาทีหลังเปิดเครื่อง ตอนนี้ยังเป็นผลจากการรีบูตครั้งเดียว

ระหว่างทางเราแก้บั๊กในสคริปต์ของลำโพงที่ตอนทำมือไม่โผล่ออกมา ถ้าแคชในแรมเมานต์ไม่สำเร็จ ตอนนี้ Soloist จะไม่เริ่มทำงาน ไม่อย่างนั้นแคชอย่างน้อย 100 MB จะไปกินแรมรวมของลำโพงที่มีทั้งหมดแค่ 244 MB ถ้าไม่มี PulseAudio ก็ไม่เริ่มเหมือนกัน จาก p2p0 จะลบเฉพาะที่อยู่ภายใน 169.254.x.x ไม่ใช่ที่อยู่ไหนก็ได้ โหมด barrier CP15 ทำงานแบบ “ปิดไว้ก่อนเป็นค่าเริ่มต้น”: เปิดไม่สำเร็จก็ไม่เริ่ม เพื่อไม่ให้ตกลูปไม่รู้จบ และตอนหยุดจะคืนค่าเดิม ประโยคที่มีคำว่า “spotifay” แต่ไม่มีคำสั่งที่เข้าใจได้จะไม่เปิดเพลงอีกแล้ว บรรทัดเอาต์พุตของ Soloist ที่มีคีย์จะไม่ถูกเขียนลงล็อก ชื่อลำโพง อินเทอร์เฟซ และขนาดแคชย้ายไปอยู่ในไฟล์ตั้งค่า

เราทดสอบแบบที่เชื่อผลเทสต์ได้ สคริปต์ของลำโพงผ่านเทสต์ 29 ตัวภายใต้ busybox ซึ่งเป็นเชลล์ฉบับลดขนาดตัวเดียวกับที่อยู่บนลำโพง ตัวประกอบชุดผ่านอีก 17 ตัว จากนั้นเราย้อนการแก้ไขทั้ง 20 จุดทีละจุด แล้วดูว่าเทสต์ของมันจะแดงไหม แดงทุกครั้ง แปลว่าเทสต์จับบั๊กตัวนั้นจริง ไม่ใช่แค่เขียวไปเรื่อย ข้อสังเกตหนึ่งของ Codex เรื่องโพรเซส aplay “ซอมบี้” ทำซ้ำไม่ได้ และเราไม่นับมันเป็นสิ่งที่แก้แล้ว นอกจากนี้เทสต์ยังจับบั๊กได้อีกห้าตัวที่เป็นความผิดพลาดของ Claude เอง ซึ่งเป็นผู้เขียนสคริปต์ เช่น ตัวสังเกตการณ์เสียงไม่หยุดไปพร้อมกับบริการ

แต่มีสามเรื่องที่เจอได้จากลำโพงจริงเท่านั้น ในเทสต์ที่ใช้ stub มองไม่เห็น adb บน Windows ส่งท้ายบรรทัดมาเป็น \r\r\n และการแยกวิเคราะห์คำตอบก็พัง adb บนลำโพงทิ้งคำสั่งที่ยาวเกินราว 4 KB แบบเงียบ ๆ และโพรเซสเบื้องหลังที่รันผ่าน adb ตาย: เซสชันปิดก่อนที่โพรเซสจะแยกตัวทัน ที่ช่วยได้คือหน่วงเวลาสองวินาที

ตัวติดตั้งอยู่ในรีโพแบบเปิด yandex-station-lite-spotify ภายใต้สัญญาอนุญาต MIT ในนั้นมีตัวประกอบชุด การติดตั้งผ่าน ADB พร้อมการย้อนกลับ สคริปต์ของลำโพงรวมทั้งการซิงก์ระดับเสียงและคำสั่งเสียง เทสต์ และ README ภาษารัสเซียพร้อมย่อหน้าสั้น ๆ ภาษาอังกฤษ ไม่มี Soloist และคีย์อยู่ในนั้น: ตัวประกอบดาวน์โหลดไคลเอนต์จากเซิร์ฟเวอร์ของ Spotify ให้ผู้ใช้แต่ละคน

จากรีโพเดียวกัน นี่คือแผนภาพสิ่งที่ทำงานอยู่บนลำโพงในที่สุด:

แผนภาพ: แอป Spotify ควบคุม Soloist บนลำโพง Soloist เล่นผ่าน PulseAudio ลง FIFO ยามเปิด aplay ดั้งเดิมเฉพาะตอนที่เพลงเล่น และเสียงเข้า mixer รวม dmix พร้อมเสียงของอลิซ ข้าง ๆ มีสคริปต์สองตัว: ซิงก์ระดับเสียงกับอลิซ และคำสั่งเสียงผ่าน Quasar Bridge

เราเสนอสูตรพร้อมตัวติดตั้งไปที่วิกิของคอมมูนิตี้ภาษารัสเซีย hackalice.me ด้วย PR ในรีโพ yandex-station-extended (ภาษารัสเซีย) รอผู้ดูแลตัดสินใจ หลังติดตั้งใหม่ เราตรวจทั้งเสียงด้วยหูและคำสั่งเสียง ทุกอย่างใช้ได้ แต่การติดตั้งบนลำโพงที่ยังไม่เคยลงอะไรผ่านแค่เทสต์เท่านั้น: บนลำโพงของเราพื้นที่ไม่พอสำหรับสำเนาเต็มชุดที่สอง

แถมท้าย: เทเลเมทรีของ Yandex

คนรู้จักถามเรื่องง่าย ๆ ว่า ลำโพงส่งอะไรไปให้ Yandex บ้างไหม เราตรวจโดยไม่เปลี่ยนอะไรเลย: ถ่ายสแนปช็อตการเชื่อมต่อเครือข่าย 40 ครั้งใน 80 วินาที ลำโพงติดต่อ clck.yandex.net ซึ่งเป็นปลายทางของล็อกและ product event และ report.appmetrica.yandex.net ซึ่งเป็นบริการวิเคราะห์ AppMetrica บวกกับช่องทางถาวรของอลิซเอง uniproxy.alice.yandex.net ที่ฝั่งเราบริดจ์ถือไว้ Spotify ติดต่อแค่ Google Cloud นี่คือเทเลเมทรีปกติของเฟิร์มแวร์ root ไม่ส่งผลอะไรกับมัน

บนลำโพงของเรามองไม่เห็นว่าส่งอะไรออกไปบ้าง เพราะทุกอย่างเข้ารหัส แต่ในวิกิของคอมมูนิตี้มีบทวิเคราะห์เทเลเมทรีโดยละเอียด (ภาษารัสเซีย) ที่ทำบน Station Midi ตามบทวิเคราะห์นั้น ทุกรายงานของ AppMetrica มีหมายเลขซีเรียลของอุปกรณ์ รุ่น เวอร์ชันเฟิร์มแวร์ และสตริงเวอร์ชันเคอร์เนลแบบเต็ม

เราปิดมันด้วยวิธีจากวิกิเดียวกัน ชื่อเซิร์ฟเวอร์เมตริกแบบตรงตัวถูกชี้กลับมาที่ตัวลำโพงเองผ่านไฟล์ /etc/hosts ลำโพงดูไฟล์นี้ก่อน DNS ของตัวเอง โปรแกรมของ Yandex ที่ส่งไปที่อยู่เหล่านี้จึงวนกลับเข้าหาตัวเอง ปิดไปเจ็ดชื่อ: clck.yandex.net, report.appmetrica.yandex.net, startup.mobile.yandex.net, startup.appmetrica.yandex.net และชื่อแบบเดียวกันบน yango.com ต่างจากสคริปต์ในวิกิตรงที่เราเขียนบรรทัดสำหรับ IPv6 ไว้ด้วย เพราะของเราเทเลเมทรีวิ่งผ่าน IPv6 พอดี พาร์ทิชันระบบเปิดให้เขียนได้เฉพาะตอนแก้ไข สำเนาไฟล์เดิมเก็บไว้แล้ว ย้อนกลับได้ด้วยคำสั่งเดียว เราไม่ได้แตะช่องทางของอลิซ การซิงก์ หรือการอัปเดตการตั้งค่า และไม่ได้แตะ Spotify กับบริดจ์ด้วย

ก่อนปิดกั้น ใน 80 วินาทีมีการเชื่อมต่อกับเซิร์ฟเวอร์เทเลเมทรีเก้าครั้ง หลังปิดกั้น ไม่มีเลยในสามนาที โพรเซสเทเลเมทรีเองไม่ล่มและยังทำงานต่อ แค่ส่งอะไรออกไปไม่ได้ คิวของสิ่งที่ยังไม่ได้ส่งมีขีดจำกัด: ราวหนึ่งเมกะไบต์บนดิสก์ ที่เหลือเก็บในหน่วยความจำ สิบนาทีหลังปิดกั้น ในหน่วยความจำสะสมไว้ 168 KB และโพรเซสเทเลเมทรีไม่ได้รีสตาร์ตเลยสักครั้ง อลิซและ Spotify ยังถือการเชื่อมต่อของตัวเองไว้ และทดสอบด้วยเสียงแล้วด้วย: อลิซตอบได้ คำสั่ง “sprosi neyroset” ส่งไปหา Mia ผ่านบริดจ์ และ Spotify เล่นเพลง

ข้อแม้หนึ่ง การบันทึกเสียงพูดเป็นอีกช่องทางหนึ่ง ซึ่งควบคุมด้วยการตั้งค่า “Pomogat Alise stat luchshe” (“ช่วยให้อลิซเก่งขึ้น”) ใน Yandex ID และการปิดกั้นผ่าน /etc/hosts ไม่เกี่ยวกับมัน

สิ่งที่ยังไม่พร้อม

การค้นหาด้วยเสียง “Vklyuchi Zemfiru v spotifay” (“เปิด Zemfira ใน Spotify” โดย Zemfira เป็นนักร้องร็อกชาวรัสเซีย) จะไม่ได้ผล: ลำโพงทำได้แค่เล่นต่อ หยุดชั่วคราว และเปลี่ยนเพลง

บิลด์ Soloist หมดอายุราว 4 กุมภาพันธ์ 2570 หลังจากนั้นทุก 90 วัน ต้องเอาเวอร์ชันใหม่จากเซิร์ฟเวอร์ทางการของ Spotify นี่เป็นสิ่งเดียวที่ยังต้องทำด้วยมือ

การทำงานต่อเนื่องนาน ๆ ก็ยังเป็นคำถาม: การทดสอบที่นานที่สุดคือเปิดเพลงราวสิบนาที สามชั่วโมงผ่านไปจะเป็นอย่างไร เรายังไม่ได้ทดสอบ

พูดตรง ๆ เรื่องขอบเขต

  • นี่คือการทดลองหนึ่งครั้งบนลำโพงหนึ่งตัว ทุกอย่างที่เล่ามาทดสอบบน Station Lite 1 ของเรา ซึ่งใช้แอมป์ ntp8910a ในสูตรของคอมมูนิตี้สำหรับรุ่นเดียวกันมีแอมป์อีกตัวด้วย คือ tas5825m แปลว่าฮาร์ดแวร์มีหลายรีวิชัน เรายังไม่ได้ทดสอบว่าวิธีของเราใช้กับรีวิชันอื่นได้ไหม
  • ต้องมี root ทั้งเรื่องตั้งอยู่บนสิทธิ์ผู้ดูแลระบบจากตอนแรก และนั่นคือการแทรกแซงเฟิร์มแวร์: ลำโพงอาจเลิกทำงาน ส่วนผลต่อการรับประกันและการกู้คืน ให้ตรวจสอบแยกเอง
  • แจกไฟล์ Soloist สำเร็จรูปไม่ได้ Spotify ห้ามไว้ จึงจะไม่มีไฟล์แบบ “โหลดแล้วลงได้เลย” ไคลเอนต์ต้องเอาจากหน้าทางการของ Spotify for Developers เท่านั้น ส่วนคีย์ต้องเป็นของคุณเอง ออกบนบัญชี Premium ของคุณเอง
  • ต้องใช้ API key ทุกครั้งที่รัน และ Spotify ขอตรง ๆ ให้ดูแลมันเหมือนรหัสผ่าน ในบทความนี้แน่นอนว่าไม่มีคีย์ แต่บนลำโพง คีย์มองเห็นได้ในรายการโพรเซส: Soloist 1.3.10 ไม่มีวิธีส่งคีย์แบบอื่น บนลำโพงไม่มีผู้ใช้อื่น เราจึงยอมรับข้อนี้
  • ไตรมาสละครั้งต้องดูแล นี่ไม่ใช่ลงแล้วลืม แต่เหมือนสมัครรับงานเล็ก ๆ ทุกสามเดือน

หลุมพราง: สรุปสั้น ๆ สำหรับคนกันเอง

ตัวติดตั้งช่วยลดงานมือไปได้มาก แต่บนลำโพงที่ยังไม่เคยลงอะไร มันผ่านแค่เทสต์ ดังนั้นนี่ยังไม่ใช่คู่มือแบบ “ทำตามนี้แล้วใช้ได้แน่” ข้างล่างคือจุดที่กินเวลาเรามากที่สุดในการทดลองนี้ เริ่มจากตรงนี้

  • เห็น Unable to load key และ librespot ข้ามเพลงไปเรื่อย ๆ นี่คือปัญหาที่รู้กันของโปรเจกต์ ไม่ใช่การติดตั้งของคุณผิด บนบัญชีของเรามันทำให้เล่นเพลงไม่ได้เลย และนักพัฒนาไม่มีทางเลี่ยงให้ ลอง librespot ก่อนจะลงอะไรจริงจัง
  • Soloist ต้องการ glibc 2.38 และ PulseAudio หรือ PipeWire บน Station Lite มีแค่ glibc 2.30 และ ALSA จึงต้องมีชุดไลบรารีของตัวเองในโฟลเดอร์แยก และรันผ่าน loader ของตัวเองด้วย --library-path อย่าใส่ path นี้ให้บริการระบบ: โปรแกรมของ Yandex คอมไพล์มากับไลบรารีเก่า
  • ไลบรารีเสียงจาก Debian รุ่นใหม่บนเคอร์เนล 4.9 เปิดการ์ดเสียงไม่ได้: SYNC_PTR ตอบ ENOTTY สิ่งที่ใช้ได้สำหรับเราคือส่งเอาต์พุตจาก PulseAudio ลง FIFO แล้วให้ aplay ดั้งเดิมของลำโพงเล่น
  • เห็นลำโพงแต่มือถือเชื่อมต่อไม่ได้ และเธรดหลักกิน CPU ให้ดูใน dmesg ว่ามี “CP15 Barrier” ไหม สำหรับเรา อาการค้างหายด้วย echo 2 > /proc/sys/abi/cp15_barrier การตั้งค่านี้อยู่ได้จนกว่าจะรีบูต
  • มือถือมองไม่เห็นลำโพง ให้ดูว่ามีที่อยู่ IPv4 บน p2p0 ไหม หลังเราลบออก การค้นหาอุปกรณ์ก็ใช้ได้
  • อย่าเปิด aplay ค้างไว้ตลอด และอย่าฆ่ามันด้วย kill -9 เรารันมันเฉพาะตอนเล่นเพลง และหยุดด้วย SIGINT
  • รันทุกอย่างผ่าน setsid nohup ไม่อย่างนั้นโพรเซสจะตายไปพร้อมเซสชันดีบักที่ปิด
  • แคชของ Soloist โตเร็ว: เพลงห้านาทีได้ 15 MB อย่าวางไว้บนพาร์ทิชันเดียวกับข้อมูลของ Yandex สำหรับเรา tmpfs ขนาด 12 MB ก็พอ
  • อย่ารีบูตลำโพงถ้าเพิ่มเครือข่ายบ้านเองแล้วยังไม่ได้ล็อกไว้: ตอนบูต Yandex จะเขียนรายการเครือข่ายใหม่จากฐานข้อมูลของตัวเอง
  • ถ้าคำสั่งเสียงผ่านเอเจนต์บน Hermes จำไว้ว่า: คำขอที่ขึ้นต้นด้วยประโยคเดียวกัน มันจะรวมเป็นเซสชันเดียวพร้อมประวัติ คำตอบทดสอบแรกของเรา “เปิด Spotify ไม่ได้” ไปติดกับประโยค “vklyuchi spotifay” และตอบซ้ำแบบนั้นจนเราลบเซสชันนั้นทิ้ง
  • ปุ่มของลำโพงและ “Alisa, gromche” เปลี่ยนแค่เสียงของอลิซ ไม่ใช่ Spotify ระดับเสียงของอลิซ (0–20) อยู่ในไฟล์ /data/quasar/data/last_vendor_volume ส่งให้ Soloist ด้วยคำสั่ง soloist ctl volume โดยแปลงเป็นสเกล 0–100
  • ถ้าปิดกั้นเทเลเมทรีผ่าน /etc/hosts ให้เขียนชื่อสำหรับ IPv6 (::1) ด้วย ไม่ใช่แค่ 127.0.0.1 บนลำโพงของเรา เทเลเมทรีวิ่งผ่าน IPv6
  • ถ้าติดตั้งจาก Windows ผ่าน adb ระวังสามเรื่อง: ท้ายบรรทัดในคำตอบมาเป็น \r\r\n คำสั่งที่ยาวเกินราว 4 KB หายไปเงียบ ๆ และโพรเซสเบื้องหลังอาจตายไปพร้อมเซสชันที่ปิด ให้เวลามันสักสองวินาทีเพื่อแยกตัว

ต่อจากนี้

ทั้งสองอย่างที่เจอในระดับตัว Soloist เอง คือลูปไม่รู้จบตรงที่เคอร์เนลดัก barrier แบบเก่า และการตอบผิดเครือข่ายเมื่อ p2p0 ยังทำงานอยู่ เราเขียนไว้ในรีโพทางการของ Spotify แล้ว: issue #32 และ issue #33 กลไกของเรื่องแรกก็ระบุไว้ที่นั่นว่าเป็นสิ่งที่สันนิษฐาน ไม่ใช่สิ่งที่พิสูจน์แล้ว Spotify ยังไม่ตอบ

ส่วนลำโพงตอนนี้ก็เลิกเป็นการทดลองคืนเดียวไปแล้ว ถอดปลั๊ก เสียบกลับ รอไม่กี่นาทีก็พูดว่า “Alisa, vklyuchi spotifay” ได้: ลำโพงบ้าน ๆ ธรรมดาที่ทำได้มากกว่าที่ควรจะทำได้ ฟังอลิซ ตอบด้วยหัวสมองของ Mia และเล่น Spotify

ถ้าคุณชอบงานทำเองกับลำโพงและเอเจนต์แบบนี้ แวะมาที่แชทของเรา (แชทใช้ภาษารัสเซีย): เราจะเล่าว่าหลุมพรางอยู่ตรงไหน และให้ฟังว่าของจริงเสียงเป็นอย่างไร

แหล่งข้อมูล

  1. Spotify for Developers: ประกาศเปิดตัว Spotify Soloist
  2. Spotify for Developers: เอกสาร Soloist
  3. Spotify for Developers: บรรทัดคำสั่งของ Soloist
  4. librespot: issue #1649, Audio key error
  5. spotify/soloist: issue #32, ลูปไม่รู้จบบนเคอร์เนลที่จำลองคำสั่ง CP15
  6. spotify/soloist: issue #33, mDNS เมื่อมีอินเทอร์เฟซ p2p0
  7. GitHub: ตัวติดตั้ง Spotify Soloist สำหรับ Yandex Station Lite
  8. yandex-station-extended: สูตร Soloist ที่เสนอสำหรับ Station Lite (PR #170)
  9. yandex-station-extended: บทวิเคราะห์เทเลเมทรีของ Yandex Station
คนกันเองอยู่ใกล้ ๆถามคนกันเอง แชทตอบเร็วกว่าค้นหาเองแชทหลักของไอที ปาร์ตี้ พัทยา: คนสาย IT สายดิจิทัล และผู้ประกอบการ ที่เคยผ่านเรื่องเดียวกันมาแล้ว เริ่มตั้งแต่กรกฎาคม 2566 แชทใช้ภาษารัสเซีย ชาวต่างชาติและคนไทยเข้ามาได้เสมอเข้าแชท (ภาษารัสเซีย)

อ่านเรื่องที่เกี่ยวข้อง