Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Integrare le YouTube Data API su Android

Un tutorial completo ed esaustivo che mostra come integrare ed utilizzare le YouTube API per sviluppare un'app mobile per Android.
Un tutorial completo ed esaustivo che mostra come integrare ed utilizzare le YouTube API per sviluppare un'app mobile per Android.
Link copiato negli appunti

YouTube si è affermata in questi anni come la più nota e utilizzata piattaforma per la condivisione e la visualizzazione di video sia da mobile sia da desktop. In particolare, negli ultimi anni, la sempre crescente popolarità dei contenuti offerti ha fatto sì che fosse indispensabile integrare i dati e le informazioni offerte da YouTube nelle proprie web app e applicazioni.

Per rendere questo compito semplice per gli sviluppatori, Google ha realizzato (e migliorato nel corso degli anni) le API per la fruizione e la gestione dei contenuti audiovisivi offerti da YouTube e che prendono il nome di YouTube Data API v3. In particolare, le funzionalità offerte dalle API sono molteplici, come la possibilità di visualizzare video e di ottenerne il thumbnail.

In questo articolo analizzeremo nel dettaglio i passi da compiere per integrare le YouTube Data API a partire da un nuovo progetto Android per visualizzare un video e una lista di thumbnails. In particolare, quando l'utente cliccherà sul thumbnail il video corrente verrà sostituito da quello selezionato.

Abilitazione delle YouTube Data API v3

Come tutte le API fornite da Google, anche le YouTube Data API v3 devono essere abilitate tramite la Google API Console per poter essere integrate nell'applicazione Android. Per ottenere la chiave è necessario compiere i seguenti passi:

  • ottenere la chiave hash SHA-1 per il debug;
  • creare un nuovo progetto sulla Google Developer Console;
  • abilitare le YouTube Data API v3;
  • restringere l'utilizzo della chiave solo alle app Android e per la chiave hash SHA-1 fornita.
  • Procedendo in ordine, apriamo una finestra del nostro terminale e spostiamoci all'interno della cartella bin della jdk installata sulla nostra macchina ed eseguiamo il comando:

    keytool -exportcert -alias androiddebugkey -keystore ~/.android/debug.keystore -list -v

    quando verrà richiesta la password per generare le chiavi hash, basterà digitare la parola android keytool

    Figura 1. Output del comando keytool (click per ingrandire)

    Output del comando keytool

    Infine, copiamo la chiave hash SHA-1 poiché la utilizzeremo più avanti in questa guida.

    Colleghiamoci, ora, alla Google API Console

    Figura 2. Modale per la creazione o selezione di un progetto (click per ingrandire)

    Modale per la creazione o selezione di un progetto

    Clicchiamo su Nuovo Progetto YouTubeDataApiTutorial Crea

    Figura 3. Schermata di creazione di un nuovo progetto (click per ingrandire)

    Schermata di creazione di un nuovo progetto

    Al termine della creazione, selezioniamo il progetto appena creato per visualizzare la dashboard.

    Figura 4. Dashboard del progetto (click per ingrandire)

    Dashboard del progetto

    Clicchiamo sulla voce Libreria YouTube Data API v3

    Figura 5. Risultato della ricerca della API (click per ingrandire)

    Risultato della ricerca della API

    Clicchiamo sul risultato ottenuto per essere rimandati alla pagina di dettaglio della libreria. In questa scheda di dettaglio sono reperibili le informazioni essenziali della libreria (descrizione, ultima data di aggiornamento, ecc.) ed è possibile abilitare e testare le API fornite.

    Figura 6. Scheda della libreria YouTube Data API v3 (click per ingrandire)

    Scheda della libreria YouTube Data API v3

    Abilitiamo la libreria cliccando sul bottone abilita e attendiamo il caricamento della dashboard dell'API.

    Figura 7. Dashboard della YouTube Data API v3 (click per ingrandire)

    Dashboard della YouTube Data API v3

    Come tutti i servizi ed API offerti da Google, per il funzionamento è necessario creare delle credenziali di accesso. Per farlo clicchiamo sul bottone Crea Credenziali Credenziali

    • le YouTube Data API v3 come scelta per le API utilizzate;
    • Android come dispositivo da cui verranno effettuate le chiamate al fine di limitarle;
    • Dati pubblici come tipo di dato a cui si desidera accedere tramite l'applicazione.

    Cliccando su Di quali credenziali ho bisogno?

    Figura 8. Scheda di creazione delle credenziali del servizio abilitato (click per ingrandire)

    Scheda di creazione delle credenziali del servizio abilitato

    Infine, per evitare che terzi possano usare in modo malizioso le nostre credenziali ed evitare il furto di quota, restringiamo l'accesso alle credenziali appena create. Dalla dashboard del progetto clicchiamo sulla voce Credenziali

    • la data di creazione;
    • il creatore della chiave;
    • la API key;
    • il nome della chiave;
    • la sezione restrizioni.

    In quest'ultima sezione, selezioniamo la voce App Android <nome-pacchetto, chiave-SHA1>

    Figura 9. Scheda di gestione delle credenziali del servizio abilitato (click per ingrandire)

    Scheda di gestione delle credenziali del servizio abilitato

    Clicchiamo infine su salva per rendere effettive le modifiche.

    Download della libreria

    Il modo più semplice per integrare le YouTube Data API v3 in un progetto Android è quello di passare il download della libreria al seguente link.

    Apriamo la sezione Download cliccando sull'omonima voce dal menu laterale e scarichiamo l'archivio YouTubeAndroidPlayerApi-1.2.2.zip.

    Figura 10. Sezione Download delle YouTube Android Player API (click per ingrandire)

    Sezione Download delle YouTube Android Player API

    Scompattiamo l'archivio ed esploriamo la cartella generata che si compone delle seguenti sottocartelle

    Ora siamo finalmente pronti per lavorare sul progetto Android.

    Creazione e set-up del progetto

    Creiamo un nuovo progetto Android con Android Studio come illustrato in questa lezione, impostando i seguenti parametri

    Cartella Descrizione
    docs cartella contenente la libreria YouTubeAndroidPlayerApi.jar
    libs cartella contenente la libreria YouTubeAndroidPlayerApi.jar
    sample un esempio di applicazione Android
    Parametro Valore
    Application Name YouTubeDataApiTutorial
    Target API per Phone e Tablet API 19: Android 4.4 (KitKat)
    Activity Template Empty Activity
    Activity Name MainActivity

    Al termine del wizard, clicchiamo su Finish

    Nella sezione Project Project Files libs YouTubeAndroidPlayerApi.jar

    Figura 11. Struttura del progetto e integrazione della libreria YouTubeAndroidPlayerApi.jar (click per ingrandire)

    Struttura del progetto e integrazione della libreria YouTubeAndroidPlayerApi.jar

    Apriamo adesso il il build.gradle del modulo app e aggiungiamo le seguenti dipendenze.

    dependencies {
    // . . .
    implementation 'com.android.support:cardview-v7:27.1.1'
    implementation files('libs/YouTubeAndroidPlayerApi.jar')
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    implementation 'com.jakewharton:butterknife:8.8.1'
    // . . .
    }

    Clicchiamo infine su Sync Now Tools > Android > "Sync Project with Gradle Files"

    In questo modo abbiamo:

    • integrato il supporto alle cardview;
    • aggiunto la libreria butterknife di cui si è già discusso in precedenza in questa lezione
    • integrato la libreria di YouTube per la gestione dei video.

    Aggiungiamo ora un nuovo Value resource file values res

    <resources>
    <string name="youtube_data_api_key" templateMergeStrategy="preserve" translatable="false">YOUR_API_KEY</string>
    </resources>

    In questo modo l'API Key sarà facilmente caricabile all'interno dell'Activity getString Activity string.xml .gitignore

    Visualizzazione di un video tramite YouTubePlayerView

    La visualizzazione di un video tramite il player offerto dalla YouTubeAndroidPlayerAPI si compone di tre passaggi:

    Apriamo il layout activity_main.xml ConstraintLayout RelativeLayout YouTubePlayerView

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <com.google.android.youtube.player.YouTubePlayerView
    android:id="@+id/youtube_player_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"/>
    </RelativeLayout>

    Spostiamoci ora nella classe MainActivity YouTubeBaseActivity YouTubePlayer.OnInitializedListener

    public class MainActivity extends YouTubeBaseActivity implements YouTubePlayer.OnInitializedListener {
    // . . .
    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer,
    boolean wasRestored) {
    // . . .
    }
    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
    // . . .
    }
    }

    Definiamo ora l'id del video che vogliamo visualizzare e inizializziamo il widget YouTubePlayerView initialize Listener

    private final String VIDEO_ID = "2-5Wv9UGkN8";
    @BindView(R.id.youtube_player_view)
    YouTubePlayerView youTubePlayerView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);
    youTubePlayerView.initialize(getString(R.string.youtube_data_api_key), this);
    }

    L'implementazione dell'interfaccia richiede di specificare il comportamento dell'Activity onInitializationSuccess onInitializationFailure wasRestore true cueVideo cueVideo

    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer,
    boolean wasRestored) {
    if(null== youTubePlayer) return;
    if (!wasRestored) {
    youTubePlayer.cueVideo(VIDEO_ID);
    }
    }
    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult youTubeInitializationResult) {
    Toast.makeText(this, "Failed to initialize YouTube Video Player.", Toast.LENGTH_LONG).show();
    }

    Eseguiamo ora l'applicazione sul nostro dispositivo Android o sull'emulatore e otterremo il seguente risultato.

    Figura 12. Visualizzazione del trailer di un film tramite il YouTubePlayerView (click per ingrandire)

    Visualizzazione del trailer di un film tramite il YouTubePlayerView

    Come si è potuto notare, questa soluzione è facile ed immediata, ma al contempo ci costringe ad estendere la classe YouTubeBaseActivity Activity AppCompatActivity actionBar view

    Il codice completo di questa soluzione è reperibile su github al seguente link

    Visualizzazione di un video tramite YouTubePlayerSupportFragment

    Un soluzione alternativa per integrare nella propria app il player di YouTube è l'utilizzo della classe YouTubePlayerSupportFragment. Questa classe definisce un fragment contenente un oggetto di tipo YouTubePlayerView che permette la visualizzazione di video. Questo approccio non richiedere di estendere alcuna Activity fornita dalla libreria, come nel caso dell'utilizzo diretto del YouTubePlayerView, dove la nostra MainActivity estendeva la classe YouTubeBaseActivity.

    I passi da compiere sono leggermente diversi rispetto a quelli visti in precedenza. In particolare, le operazioni da compiere sono le seguenti:

    • modifica del layout per aggiungere un fragment di tipo YouTubePlayerSupportFragment
    • implementazione dell'interfaccia YouTubePlayer.OnInitializedListener
    • inizializzazione del player di YouTube.

    Iniziamo col modificare il layout activity_main.xml fragment YouTubePlayerSupportFragment

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <fragment
    android:id="@+id/youtube_fragment"
    android:name="com.google.android.youtube.player.YouTubePlayerSupportFragment"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
    </RelativeLayout>

    Apriamo la MainActivity YouTubePlayer.OnInitializedListener

    public class MainActivity extends AppCompatActivity implements YouTubePlayer.OnInitializedListener {
    // . . .
    @Override
    protected void onStart() {
    super.onStart();
    mYuoTubePlayerFrag.initialize(getString(R.string.youtube_data_api_key), this);
    }
    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer,
    boolean wasRestored) {
    // . . .
    }
    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider,
    YouTubeInitializationResult youTubeInitializationResult) {
    // . . .
    }
    // . . .
    }

    A questo punto, inizializziamo una lista di id video di YouTube e inizializziamo il YouTubePlayerSupportFragment

    private final List<String> videos =
    Arrays.asList("20bpjtCbCz0", "bI31WqFDxNs", "D86RtevtfrA", "xZNBFcwd7zc", "2-5Wv9UGkN8", "Z5ezsReZcxU");
    private static final int RECOVERY_REQUEST = 1;
    private YouTubePlayerSupportFragment mYuoTubePlayerFrag;
    private YouTubePlayer mYouTubePlayer;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);
    mYuoTubePlayerFrag =
    (YouTubePlayerSupportFragment) getSupportFragmentManager().findFragmentById(R.id.youtube_fragment);
    }
    @Override
    protected void onStart() {
    super.onStart();
    mYuoTubePlayerFrag.initialize(getString(R.string.youtube_data_api_key), this);
    }

    Analogamente a quanto visto con il YouTubePlayerView YouTubePlayerSupportFragment Listener

    Implementiamo, adesso, i metodi del Listener YouTubePlayer

    In caso di successo, verificheremo se il player è ripristinato da uno stato salvato in precedenza. Se così non fosse, imposteremo il video da visualizzare tramite la funzione cueVideo

    In caso di fallimento, verificheremo se l'errore è ripristinabile dall'utente. Se dovesse essere ripristinabile, allora verrà mostrata una finestra di dialogo per risolvere questo errore di inizializzazione. La finestra di dialogo mostrerà un messaggio localizzato sull'errore e, una volta confermata dall'utente (toccando la finestra di dialogo), indirizzerà quest'ultimo al Play Store, se l'app YouTube non è aggiornata o mancante, oppure alle impostazioni di sistema, se l'app YouTube è disabilitata sul dispositivo. Ciò è possibile grazie al metodo getErrorDialog Activity requestCode startActivityForResult

    Se invece l'errore non fosse risolvibile dall'utente, verrà mostrato un messaggio di errore tramite Toast

    Si riporta di seguito l’implementazione per completezza.

    @Override
    public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer youTubePlayer,
    boolean wasRestored) {
    if (!wasRestored) {
    mYouTubePlayer = youTubePlayer;
    mYouTubePlayer.cueVideo(videos.get(0));
    }
    }
    @Override
    public void onInitializationFailure(YouTubePlayer.Provider provider,
    YouTubeInitializationResult youTubeInitializationResult) {
    if (youTubeInitializationResult.isUserRecoverableError()) {
    youTubeInitializationResult.getErrorDialog(this, RECOVERY_REQUEST).show();
    } else {
    String error = String.format(getString(R.string.player_error), youTubeInitializationResult.toString());
    Toast.makeText(this, error, Toast.LENGTH_LONG).show();
    }
    }

    Prima di eseguire l’applicazione, disattiviamo l’applicazione di YouTube per vedere il comportamento del metodo getErrorDialog

    Figura 13. Finestra di dialogo per l’attivazione di Youtube e visualizzazione del video (click per ingrandire)

    Finestra di dialogo per l’attivazione di Youtube e visualizzazione del video

    Ora che abbiamo implementato la visualizzazione del player, aggiungiamo la lista di thumbnails.

    Creazione di una lista di thumbnail cliccabile

    La libreria YouTubeAndroidPlayerAPI offre la possibilità di visualizzare la thumbnail di un video o di una playlist di YouTube attraverso la classe YouTubeThumbnailView. Il processo per compiere tale operazione è alquanto semplice e si compone dei seguenti passi:

    • creazione di un nuovo layout per mostrare una CarView YouTubeThumbnailView
    • modifica del layout principale per l’integrazione di una RecyclerView
    • creazione di un Adapter ViewHolder RecyclerView
    • modifica della MainActivity RecyclerView

    In questa sezione ci focalizzeremo per lo più sulla creazione dell'Adapter al fine di visualizzare le thumbnail nella RecyclerView. Per ulteriori dettagli sulle RecyclerView si rimanda alla seguente lezione.

    Iniziamo con la creazione di un nuovo layout per gestire la UI della thumbnail. Cliccando con il tasto destra sulla cartella layout in res, selezioniamo New -> Layout resource file e inseriamo come nome video_item.

    Apriamo il file e sostituiamo il suo contenuto con quanto segue:

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/video_cv"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:layout_margin="6dp"
    android:background="@color/white"
    android:clickable="true"
    card_view:cardElevation="5dp"
    card_view:cardCornerRadius="5dp"
    card_view:cardBackgroundColor="@color/white"
    card_view:cardPreventCornerOverlap="true"
    card_view:cardUseCompatPadding="true"
    android:focusable="true">
    
    <com.google.android.youtube.player.YouTubeThumbnailView
    android:id="@+id/youtube_thumbnail"
    android:layout_width="match_parent"
    android:layout_height="130dp"
    android:scaleType="centerCrop"
    android:layout_gravity="center"
    android:visibility="visible"/>
    </android.support.v7.widget.CardView>

    In questo modo abbiamo creato una CardView MainActivity YouTubeThumbnailView

    Spostiamoci ora all’interno del layout activity_main e aggiungiamo all’interno del RelativeLayout una RecyclerView, che conterrà le thumbnail, e una View per separare quest’ultima dal player.

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    . . .
    <View
    android:id="@+id/separator_view"
    android:layout_width="fill_parent"
    android:layout_height="@dimen/thickness"
    android:layout_margin="@dimen/margin_10dp"
    android:background="@android:color/darker_gray"
    android:layout_below="@+id/youtube_fragment" />
    
    <android.support.v7.widget.RecyclerView
    android:id="@+id/video_rv"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_below="@+id/separator_view" />
    </RelativeLayout>

    Successivamente, creiamo una nuova classe Java che chiameremo VideoAdapter Adapter RecyclerView

    • della classe VideoAdapterViewHolder
    • dell’interfaccia VideoAdapterOnClickHandler onClick
    • la definizione del metodo setVideosData
    • dei metodi onCreateViewHolder onBindViewHolder RecyclerView

    Per l’implementazione della classe VideoAdapterViewHolder, dell’interfaccia VideoAdapterOnClickHandler e del metodo setVideosData si rimanda al seguente link.

    Vediamo invece l’implementazione della classe VideoAdapter.

    Avendo definito la classe VideoAdapterViewHolder, è possibile farla estendere alla classe VideoAdapter. Il costruttore della classe inoltre prenderà in input sia il Listener sull'evento click che le API key di YouTube che verranno utilizzate dall'oggetto YouTubeThumbnailView. Si riporta di seguito l'implementazione parziale.

    public class VideoAdapter extends RecyclerView.Adapter<VideoAdapter.VideoAdapterViewHolder>{
    // . . .
    private String mYouTubeApiKey;
    
    public VideoAdapter(VideoAdapterOnClickHandler mClickHandler, String mYouTubeApiKey) {
    this.mClickHandler = mClickHandler;
    this.mYouTubeApiKey = mYouTubeApiKey;
    }
    // . . .
    }

    Successivamente, implementiamo il metodo onCreateViewHolder VideoAdapterViewHolder video_item

    @Override
    public VideoAdapterViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    Context parentContex = parent.getContext();
    int layoutIdForListItem = R.layout.video_item;
    LayoutInflater inflater = LayoutInflater.from(parentContex);
    View view = inflater.inflate(layoutIdForListItem, parent, false);
    return new VideoAdapter.VideoAdapterViewHolder(view);
    }

    Infine, non resta che implementare il metodo onBindViewHolder YouTubeThumbnailView initialize Listener Listener onInitializationSuccess onInitializationFailure

    • viene impostato il video per il YouTubeThumbnailLoader che ha la responsabilità di caricare le thumbnails del video nella YouTubeThumbnailView
    • impostare un secondo listener sull'oggetto youTubeThumbnailLoader

    Si riporta di seguito l'implementazione del metodo.

    @Override
    public void onBindViewHolder(VideoAdapterViewHolder holder, int position) {
    final int currentPosition = position;
    
    holder.mYouTubeThumbnailView.initialize(mYouTubeApiKey, new YouTubeThumbnailView.OnInitializedListener() {
    @Override
    public void onInitializationSuccess(YouTubeThumbnailView youTubeThumbnailView, final YouTubeThumbnailLoader youTubeThumbnailLoader) {
    youTubeThumbnailLoader.setVideo(videoList.get(currentPosition));
    youTubeThumbnailLoader.setOnThumbnailLoadedListener(new YouTubeThumbnailLoader.OnThumbnailLoadedListener() {
    @Override
    public void onThumbnailLoaded(YouTubeThumbnailView youTubeThumbnailView, String s) {
    youTubeThumbnailLoader.release();
    }
    
    @Override
    public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {
    Log.e(TAG, "Youtube Thumbnail Error");
    }
    });
    }
    @Override
    public void onInitializationFailure(YouTubeThumbnailView youTubeThumbnailView, YouTubeInitializationResult youTubeInitializationResult) {
    Log.e(TAG, "Youtube Initialization Failure");
    }
    });
    
    }

    Non resta a questo punto che aggiornare la MainActivity RecyclerView

    Come primo passo, implementiamo l’interfaccia VideoAdapterOnClickHandler definita all’interno della classe Adapter come segue.

    public class MainActivity extends AppCompatActivity implements YouTubePlayer.OnInitializedListener,
    VideoAdapter.VideoAdapterOnClickHandler {
    // . . .
    
    @Override
    public void onClick(String selectedTrailer) {
    if (mYuoTubePlayerFrag != null && mYouTubePlayer != null) {
    mYouTubePlayer.cueVideo(selectedTrailer);
    }
    }
    }

    In particolare, nel corpo del metodo onClick mYuoTubePlayerFrag mYouTubePlayer

    All’interno del metodo onCreate:

    • creiamo un nuovo LinearLayoutManager RecyclerView LayoutManager RecyclerView
    • creiamo un nuovo VideoAdapter
    • impostiamo la lista degli id dei video per l’Adapter
    @BindView(R.id.video_rv)
    RecyclerView mVideoRecyclerView;
    private VideoAdapter mVideoAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    //. . .
    LinearLayoutManager trailerLayoutManager
    = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
    mVideoRecyclerView.setLayoutManager(trailerLayoutManager);
    mVideoRecyclerView.setHasFixedSize(true);
    mVideoAdapter = new VideoAdapter(this, getString(R.string.youtube_data_api_key));
    mVideoAdapter.setVideosData(videos);
    }

    Infine, impostiamo il mVideoAdapter come nuovo Adapter per la RecyclerView.

    @Override
    protected void onStart() {
    // . . .
    mVideoRecyclerView.setAdapter(mVideoAdapter);
    }

    Eseguendo l’applicazione otterremo il seguente risultato.

    Figura 14. Visualizzazione di un video con una lista di thumbnail (click per ingrandire)

    Visualizzazione di un video con una lista di thumbnail

    Il codice di questo articolo è reperibile su GitHub

    Ti consigliamo anche