Arti Zirk - Syncly MusicSync: Difference between revisions
Veel teksti |
|||
Line 45: | Line 45: | ||
== Backendi implementeerimine == | == Backendi implementeerimine == | ||
Alustasin Youtube playlisti videote lisamise ja eemaldamise eventide genereerimisega. Selleks otsustasin ära kasutada youtube-dl sisse ehitatud funktsionaalsust mis annab mulle tagasi nimekirja lugudest mis on playlistis | |||
Hetkel siis on mul üks <code>playlist-sync.py</code> fail kus on while True loop mis iga andmebaasi lisatud playlisti kohta käivitab <code>get_song_updates</code> meetodi. <code>get_song_updates</code> meetod omakorda tõmbab alla, kasutades youtube-dl teeki, ette antud youtube playlisti html lehe ning ekstraktib sealt kõigi lugude id'd ning ka lugude nimed. Peale seda kui mul on käes list loo id-ga, küsin ma andmebaasist kas need lood on juba lisatud, kui pole, lisan selle ning genereerin evendi. Selleks et teada saada kas mõni lugu on kustutatud playlistis käin ma kõik andmebaasi lisatud antud playlisti lood läbi ning testin kas nad on eelnevalt alla tõmmatud lugude listis, kui pole siis genereerin evendi et lugu on kustutatud youtube playlistist. | |||
<code>youtube-downloader.py</code> skript kuulab eelnevalt genereeritud evente ning lugude lisamise korral tõmbab nad alla youtube-dl teegi abil ja laeb nad Amazon S3'e üles kasutades boto3 teeki. | |||
<code>api.py</code> hoolitseb HTTP API eest. | |||
Hetkel implementeerib http api neli endpointi kuhu pihta on võimalik päringuid teha | |||
* <code>/playlists/</code> - kollektsioon playlistidest | |||
* <code>/playlists/{playlist_id}</code> - üks kindel playlist | |||
* <code>/playlists/{playlist_id}/songs/</code> - kollektsioon lugudest ühes playlistis | |||
* <code>/playlists/{playlist_id}/songs/{song_id}</code> - üks kindel lugu | |||
Iga see url on implementeeritud erineva klasssi poolt mis omakorda pärinevad <code>BaseResponse</code> klassist ning kõik nad tagastavad andmeid json vormingus | |||
paar näidet hetkel implementeeritud api kohta | |||
<pre>% # Küsime serveri lisatud playlistid | |||
% http GET http://localhost:8000/playlists | |||
HTTP/1.0 200 OK | |||
Date: Tue, 08 Dec 2015 13:16:33 GMT | |||
Server: WSGIServer/0.2 CPython/3.5.0 | |||
content-length: 202 | |||
content-type: application/json; charset=utf-8 | |||
[ | |||
{ | |||
"_id": "PLGE39Wpa-qf1xjp4gmJ_1PBzH7a_-GdOe", | |||
"title": "Nice Music [WIP]", | |||
"type": "YoutubePlaylist" | |||
}, | |||
{ | |||
"_id": "PLB5VrND_o3PgZNzNdohFDWE5BTFIPDImQ", | |||
"title": "Music I like", | |||
"type": "YoutubePlaylist" | |||
} | |||
] | |||
</pre> | |||
<pre>% # Küsime mis lood on ühes playlistis | |||
% http GET http://localhost:8000/playlists/PLB5VrND_o3PgZNzNdohFDWE5BTFIPDImQ/songs | |||
HTTP/1.0 200 OK | |||
Date: Tue, 08 Dec 2015 13:17:01 GMT | |||
Server: WSGIServer/0.2 CPython/3.5.0 | |||
content-length: 546 | |||
content-type: application/json; charset=utf-8 | |||
[ | |||
{ | |||
"_id": "qFDP9egTwfM", | |||
"deleted": false, | |||
"playlist": "PLB5VrND_o3PgZNzNdohFDWE5BTFIPDImQ", | |||
"title": "Netsky - Rio (Official Video) ft. Digital Farm Animals", | |||
"type": "Youtube", | |||
"url": "http://s3.storage.ms.wut.ee/qFDP9egTwfM" | |||
}, | |||
{ | |||
"_id": "FGBhQbmPwH8", | |||
"deleted": false, | |||
"playlist": "PLB5VrND_o3PgZNzNdohFDWE5BTFIPDImQ", | |||
"title": "Daft Punk - One More Time", | |||
"type": "Youtube", | |||
"url": "http://s3.storage.ms.wut.ee/FGBhQbmPwH8" | |||
} | |||
] | |||
</pre> | |||
= Viited = | = Viited = | ||
{{Reflist}} | {{Reflist}} |
Revision as of 15:33, 8 December 2015
Esitlus
Esitluse slaidid on siin: http://slides.com/artizirk/musicsync
Syncly MusicSync
Syncly MusicSync on minu Java[1] kodu töö. Tegu on üsnagi KISS teenusega mis võimaldab kasutajal sünkroniseerida YouTube keskonnas olevaid playliste helifailidena enda telefoni.
Idee
Õues ringi jalutades või rattaga sõites meeldib mulle kõrvaklapid pähe pannes muusikat kuulata. Tavaliselt on minu muusika allikaks YouTube üles laetud lood mis on mul playlisti lisatud ning mida ma siis aegaajalt ühe väikese scriptiga enda arvuti ja sealt edasi telefoni tõmban. youtube-dl on üks väike pythonis kirjutatud programm mis oskab seda väga hästi teha.
#!/bin/bash youtube-dl -i -x --download-archive .archive.txt -f bestaudio "http://www.youtube.com/playlist?list=PLB5VrND_o3PgZNzNdohFDWE5BTFIPDImQ" adb push -p * /sdcard/Music/
Mu sõber Mark tegi selle automaatse sünkroniseerimis osa isegi ära enamvähem ning lükkas koodi githubi üles nightsnack[2] nimega aga see ei lahenda ära lugude telefoni saamis probleemi.
Sügisel algas Java progemis kursus mille raames otsutasin Javas kirjutatud Androidi rakenduse teha mis oskaks minu lugusi automaatselt telefoni tõmmata.
Planeering
Kõigepealt alustasin Androidi platvormi dokumentatsiooni lugemisega ja üritasin enamvähem paika panna mida ma androidi rakenduses kuvada tahaksin ning tegin endale enamvähem selgeks kuidas Androidi poolt ära teostada.
Selle lõpptulemuseks on midagi sellist
Edasi panin paika punktid mida mul oleks vaja et backend server teeks:
- Playlistide kuvamine / lisamine / eemaldamine
- Playlistides olevate lugude kuvamine
- Teadete genereerimine playlisti lugude lisamise/eemaldamise korral
Tehnoloogiate valik
Backend serveri kirjutamiseks tuli teha valik kuidas ma täpselt selle ära lahendan kasutades mis asju.
Playlistide ja seal olevate lugude salvestamiseks otsustasin kasutada MongoDB andmebaasi mis on üks NoSQL andmebaas JSON sarnaste dokumentide salvestamiseks. Valisin MongoDB just selle pärast, et olen seda varasemalt kasutanud, arenduse käigus andmestruktuuri muutmine on üli kerge ning kuna SQL pole mulle eriti kunagi meeldinud.
YouTubest lugude allalaadimiseks hetkel ainuke laialt toetatud varjant on kasutada youtube-dl pythoni programmi. On olemas ka erinevaid veebilehti mis oskavad YouTubest alla laadida helifaile aga ka need suuretõenäosusega kasutavad midagi sarnast tagaplaanil. Kuna youtube-dl on kirjutatud Pythonis siis on selle kasutamine Pythoni scriptides kergem ja annab rohkem võimalusi selle käitumise muutmiseks kui mõne muu lahenduse kasutamine.
Kuna mu arti.ee serverist pole eriti palju kettapinda, et sinna ka muusika ära mahutada siis otsustasin kasutada Amazon S3 pilveservereid kuhu Youtubest allalaetud muusika paigutada ning sealt neid vajadusel telefoni tõmmata.
Genereeritud teadete edastamiseks sobib mulle väga hästi nginx-push-stream-module mis võimaldab kergesti genereerida Server Sent Events striimi mida on võimalik töödelda väga kergelt kõigi programeerimis keeltega ja veebilehitsejatel on sse tarbimise jaoks sisseehitatud tugi javascriptis.
HTTP API ehitamiseks, mille kaudu teha päringuid serveri pihta, otsustasin teha kasutades Pythoni teeki nimega Falcon. Falcon on minimaalne Pythoni WSGI liidest täitev teek HTTP RESTful api'de tegemiseks. Siin on näide sellst kui ilus lõpptulemus jääb kasutades Falconit https://gist.github.com/artizirk/ae9cf28d1f45ef0aa965
Backendi implementeerimine
Alustasin Youtube playlisti videote lisamise ja eemaldamise eventide genereerimisega. Selleks otsustasin ära kasutada youtube-dl sisse ehitatud funktsionaalsust mis annab mulle tagasi nimekirja lugudest mis on playlistis
Hetkel siis on mul üks playlist-sync.py
fail kus on while True loop mis iga andmebaasi lisatud playlisti kohta käivitab get_song_updates
meetodi. get_song_updates
meetod omakorda tõmbab alla, kasutades youtube-dl teeki, ette antud youtube playlisti html lehe ning ekstraktib sealt kõigi lugude id'd ning ka lugude nimed. Peale seda kui mul on käes list loo id-ga, küsin ma andmebaasist kas need lood on juba lisatud, kui pole, lisan selle ning genereerin evendi. Selleks et teada saada kas mõni lugu on kustutatud playlistis käin ma kõik andmebaasi lisatud antud playlisti lood läbi ning testin kas nad on eelnevalt alla tõmmatud lugude listis, kui pole siis genereerin evendi et lugu on kustutatud youtube playlistist.
youtube-downloader.py
skript kuulab eelnevalt genereeritud evente ning lugude lisamise korral tõmbab nad alla youtube-dl teegi abil ja laeb nad Amazon S3'e üles kasutades boto3 teeki.
api.py
hoolitseb HTTP API eest.
Hetkel implementeerib http api neli endpointi kuhu pihta on võimalik päringuid teha
/playlists/
- kollektsioon playlistidest/playlists/{playlist_id}
- üks kindel playlist/playlists/{playlist_id}/songs/
- kollektsioon lugudest ühes playlistis/playlists/{playlist_id}/songs/{song_id}
- üks kindel lugu
Iga see url on implementeeritud erineva klasssi poolt mis omakorda pärinevad BaseResponse
klassist ning kõik nad tagastavad andmeid json vormingus
paar näidet hetkel implementeeritud api kohta
% # Küsime serveri lisatud playlistid % http GET http://localhost:8000/playlists HTTP/1.0 200 OK Date: Tue, 08 Dec 2015 13:16:33 GMT Server: WSGIServer/0.2 CPython/3.5.0 content-length: 202 content-type: application/json; charset=utf-8 [ { "_id": "PLGE39Wpa-qf1xjp4gmJ_1PBzH7a_-GdOe", "title": "Nice Music [WIP]", "type": "YoutubePlaylist" }, { "_id": "PLB5VrND_o3PgZNzNdohFDWE5BTFIPDImQ", "title": "Music I like", "type": "YoutubePlaylist" } ]
% # Küsime mis lood on ühes playlistis % http GET http://localhost:8000/playlists/PLB5VrND_o3PgZNzNdohFDWE5BTFIPDImQ/songs HTTP/1.0 200 OK Date: Tue, 08 Dec 2015 13:17:01 GMT Server: WSGIServer/0.2 CPython/3.5.0 content-length: 546 content-type: application/json; charset=utf-8 [ { "_id": "qFDP9egTwfM", "deleted": false, "playlist": "PLB5VrND_o3PgZNzNdohFDWE5BTFIPDImQ", "title": "Netsky - Rio (Official Video) ft. Digital Farm Animals", "type": "Youtube", "url": "http://s3.storage.ms.wut.ee/qFDP9egTwfM" }, { "_id": "FGBhQbmPwH8", "deleted": false, "playlist": "PLB5VrND_o3PgZNzNdohFDWE5BTFIPDImQ", "title": "Daft Punk - One More Time", "type": "Youtube", "url": "http://s3.storage.ms.wut.ee/FGBhQbmPwH8" } ]