UniTO/anno3/progmobile/presentazione/index.html
2024-10-29 09:11:05 +01:00

335 lines
16 KiB
HTML
Executable file

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>Apollon App</title>
<link rel='shortcut icon' href='https://framecca.github.io/Apollon/img/Apollon.png' type='image/x-icon' />
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/Apollon.css">
<!-- Theme used for syntax highlighting of code -->
<link rel="stylesheet" href="lib/css/monokai.css">
<!-- Printing and PDF exports -->
</head>
<body>
<style>
small {
font-size: 5px;
}
</style>
<div class="reveal">
<div class="slides">
<section>
<img src = "img/logo.png">
<p style = "color: #e5c100">Borello Nazareno - Galatola Marco - Mecca Francesco</p>
</section>
<section>
<section data-markdown>
<textarea data-template>
## Cos'è Apollon?
Un'applicazione che permette lo streaming e l'organizzazione della propria libreria musicale da PC a dispositivi Android
Si divide in due parti, un client Android, sul quale si concentra la presentazione, ed un server PC, entrambi sviluppati in Kotlin
</textarea>
</section>
<section data-markdown>
<textarea data-template>
## Caratteristiche principali
* Streaming in tre preset di qualità
* Multiutente
* Gestione playlist personalizzate
* Possibilità di eseguire ricerche sulla propria libreria
* Notifiche interattive
* Supporto completo per quattro lingue: Inglese, Francese, Italiano e Swahili
* Layout del player alternativo per schermi più lunghi
* Condivisione tramite app esterne del brano in ascolto
</textarea>
</section>
<section data-markdown>
<textarea data-template>
<img class="left_img" src="img\ApolloCensored.png">
<br>
<h2>Perché Apollon?</h2>
Il nome omaggia Apollo, dio greco della musica e della poesia, mentre il logo rappresenta la lira tipicamente associata alla divinità
</textarea>
</section>
<section data-markdown>
<textarea data-template>
## Confronto con Spotify ed Apple Music
| | <img src="img\Spot.png"> | <img src="img/am2.jpg"> | <img src="img\Apollon.png"> |
|:---------------------:|:------------------------:|:----------------------:|:---------------------------:|
| **Qualità** (kbps) | [128/256](https://support.spotify.com/us/article/high-quality-streaming/) | [&le;256](https://www.theverge.com/2019/8/7/20758633/apple-digital-masters-itunes-rebrand-music-quality) |[160, 256, 500](https://wiki.audacityteam.org/wiki/OGG)|
| **Censura** | Sì | Sì | No |
| **Gestione catalogo** | Azienda | Azienda | Utente |
| **DRM** | Sì | Sì | No |
| **Costo** | Ads/Fee | Fee | Open Source |
</textarea>
</section>
<section data-markdown>
<textarea data-template>
## Il nostro target di utenti
Apollon si rivolge a quegli appassionati di musica
che non vogliono rinunciare alla propria collezione anche lontano da casa
Il backend si basa su MPD, un software Linux ampiamente diffuso come riproduttore fra
la comunità di audiofili
</textarea>
</section>
</section>
<section>
<section data-markdown>
<textarea data-template>
<h3>Come un media player tradizionale</h3>
<img src="img\player.png" class="left_img small_img">
<br><br>
Vengono offerte tutte le funzionalità di un media player tradizionale:
<ul>
<li>Play/Pause</li>
<li> Skip</li>
<li> Loop</li>
<li> Riproduzione casuale</li>
<li> Seek</li>
<li> Riproduzione in background</li>
</ul>
</textarea>
</section>
<section data-markdown>
<textarea data-template>
## Schema media player
<br>
<img class="big_img" src="img\playerArch.png">
</textarea>
</section>
<section>
<h4>Audio manager e Audio focus</h4>
<p>AudioManager ci permette di gestire l'interazione con gli eventi esterni all'applicazione, come notifiche, chiamate, gestione del volume.</p>
<script src="https://gist.github.com/FraMecca/11c3dd5b8f20cfb52c5620c9f9ad9262.js"></script>
</section>
<section data-markdown>
<textarea data-template>
## Sfondo e Notifiche
<img src="img\notification.png" class="left_img small_img">
<br><br>
Quando un brano è in riproduzione viene generata una notifica interattiva contenente i metadati rilevanti
Inoltre l'immagine associata viene impostata come sfondo della schermata di blocco
</textarea>
</section>
<section>
<h4>Implementazione di sfondo e notifiche</h4>
<script src="https://gist.github.com/FraMecca/a1855beac5cee1e1fa1e83e489317898.js"></script>
</section>
<section data-markdown>
<textarea data-template>
## Miniplayer
<img src="img\miniplayer.png" class="left_img small_img">
<br><br>
Il miniplayer permette un controllo basilare sulla riproduzione mentre si naviga l'applicazione
<br><br>
Al tocco si viene riportati al player esteso
</textarea>
</section>
<section >
<h2>Ottimizzazione</h2>
<p>Le risorse vengono liberate quando il player rimane inutilizzato per tre minuti</p>
<script src="https://gist.github.com/FraMecca/0395c9f879e0d399f6cfbc40b1921833.js"></script>
</section>
</section>
<section>
<section data-markdown>
<textarea data-template>
## Oltre un media player tradizionale
Vengono offerte alcune funzionalità aggiuntive oltre a quelle descritte in precedenza:
* Testo della canzone
* Supporto per le gesture
* Multilingua
* UI alternativa
</textarea>
</section>
<section data-markdown>
<textarea data-template>
### Lyrics
<img src="img\lyrics.png" class="left_img small_img">
<br>
<br>
Ottenute dal server da ChartLyrics, convertite in JSON ed inviate al client
</textarea>
</section>
<section data-markdown>
<textarea data-template>
## Gestures
<img src="gifs\favourite.gif" class="ros_img" style="margin-right:160px"><img src="gifs\swipe.gif" class="ros_img">
</textarea>
</section>
<section>
<h4>Implementazione delle Gestures</h4>
<script src="https://gist.github.com/FraMecca/2970cc4b600a6ebb2559fc26136062b6.js"></script>
</section>
<section data-markdown>
<textarea data-template>
## Multilingua
* supporto per quattro lingue: Italiano (it_IT), Francese (fr_FR), Inglese (en_US) e Swahili (sw_UG)
* ottenuto tramite `Locale resource-resolution` (api &gt=24)
* Un file string.xml per ogni lingua supportata
</textarea>
</section>
<section data-markdown>
<textarea data-template>
### Layout player alternativo
<img class="small_img" src="img\player.png" style="margin-right=20px"><img class="small_img" src="img\player_long.png">
</textarea>
</section>
</section>
<section>
<section data-markdown>
<textarea data-template>
### Architettura Client Server
<img class="big_img" src="img\s_arch.png">
</textarea>
</section>
<section data-markdown>
<textarea data-template>
## Comunicare col server
La comunicazione avviene tramite un Singleton che espone funzioni gestite da AsyncTask e mantiene una cache
dei risultati ricevuti
<br><br>
Ad ogni AsyncTask è assegnato un TaskListener, chiamato asincronicamente ad operazione conclusa,
il quale riceve un TaskResult (specifico per l'operazione) atto a modellare il risultato richiesto
<br><br>
Questo sistema fa sì che le operazioni di backend non blocchino la UI, preservando il più possibile l'interattività
con l'utente
</textarea>
</section>
<section>
<h3>AsyncTask</h3>
<script src="https://gist.github.com/FraMecca/e599908de37fd071668635dc93bc9d3c.js"></script>
</section>
<section>
<h3>TaskListener, TaskResult e Server singleton</h3>
<script src="https://gist.github.com/FraMecca/d81657262e0e9f5183d06e2804b03672.js"></script>
</section>
<section data-markdown>
<textarea data-template>
### Complicazioni sul seeking
Non sempre è possibile fare seeking su un brano poiché la classe
MediaPlayer implementa la gestione di streaming via HTTP mentre il server utilizza il transcoding on the fly
<br><br>
Questo fa sì che la dimensione effettiva del file muti nel tempo e perciò non possa essere nota a priori,
per risolvere il problema si adotta una soluzione in due step:
* Controllare lo stato del buffer
* Se il buffer non è sufficiente, fare una richiesta `HTTP Content-Range`
</textarea>
</section>
<section>
<h2>Implementazione seek</h2>
<script src="https://gist.github.com/FraMecca/5e631d8910e446eef1e2336dc6a818d5.js"></script>
</section>
</section>
</section>
<section>
<section data-markdown>
<textarea data-template>
## Visualizzazione
La parte di visualizzazione ha richiesto l'uso di varie componenti:
* **Fragments** per mantenere il binding tra Activity e Service
* **Adapter** per visualizzare liste modulari di elementi personalizzati tramite **Card**
* **Picasso** per gestire immagini remote
</textarea>
</section>
<section data-markdown>
<textarea data-template>
## Fragment
Ogni schermata è gestita da un fragment specifico invocato dall'Activity
- I fragment sono inseriti in uno stack per permettere all'utente di tornare alle schermate precedenti
- Il nostro target di utenti ha un catalogo musicale di vaste dimensioni: per questo motivo è buona pratica utilizzare la classe [RecyclerView](https://developer.android.com/guide/topics/ui/layout/recyclerview).
</textarea>
</section>
<section data-markdown>
<textarea data-template>
### Adapter e Card
<img class="left_img small_img" src="img\albums.png">
<img class="left_img small_img" src="img\songs.png">
<br><br>
Adatper e Card gestiscono l'interfaccia dei fragment composti da liste di album o canzoni
</textarea>
</section>
<section >
<h2>Picasso</h2>
<p>
Il download ed il caching delle immagini prese dalla rete, come cover-art ed artisti, avviene utilizzando
la libreria <a><href="https://square.github.io/picasso/">Picasso</href></a>
</p>
<script src="https://gist.github.com/FraMecca/d95d00ea80ff5ed6b63e20878c7c8656.js"></script>
</section>
</section>
<section>
<section data-markdown>
<textarea data-template>
### Usare Kotlin per lo sviluppo
Kotlin ci ha permesso di usare con più facilità vari pattern architetturali e tecniche di programmazione funzionale.
* Singleton: gestione della comunicazione col server
* Companion Object: a cui viene delegata l'inizializzazione dei fragments
* Sum Types: parametrizzazione dei fragments
* Pattern Matching: semplifica la logica e la struttura del codice
</textarea>
</section>
<section >
<h4>Pattern matching e sealed classes</h4>
<script src="https://gist.github.com/FraMecca/a615a249cbf85f60fb1e9399a1bc88c8.js"></script>
</section>
<section data-markdown>
<textarea data-template>
## Backend
Apollon comunica con un backend, scritto in Kotlin, installato sul server dell'utente.
Il backend si occupa di:
- leggere il database musicale di [MPD](https://en.wikipedia.org/wiki/Music_Player_Daemon)
- convertire i brani musicali richiesti e leggere i metadati
- comunicare attraverso un'api REST-like
</textarea>
</section>
<section data-markdown>
<textarea data-template>
## API
Quattro aree funzionali
- Libreria: navigazione per album, genere, artista e ricerca
- Playlists: creazione e modifica di playlist specifiche per ogni utente
- Streaming: gestione del flusso di dati, qualita` dello stream, avanzamento, signaling delle risorse in uso
- Handle per operazioni sui singoli oggetti del catalogo: artista, album, genere, brano, metadati
</textarea>
</section>
<section >
<p>
Come nell'app, vengono utilizzati pattern architetturali tipici della programmazione ad oggetti e funzionale.
La logica del backend è codificata nei tipi <em>Response</em> e <em>Request</em> che tracciano il bordo dell'API.
</p>
<script src="https://gist.github.com/FraMecca/7350f897349834942ed8a7dd2b81ca0a.js"></script>
</section>
</section>
</div>
</div>
<script src="js/reveal.js"></script>
<script>
Reveal.initialize({
hash: true,
dependencies: [
{ src: 'plugin/markdown/marked.js' },
{ src: 'plugin/markdown/markdown.js' },
{ src: 'plugin/highlight/highlight.js' },
{ src: 'plugin/notes/notes.js', async: true }
]
});
</script>
</body>
</html>