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

Controllo della riproduzione

Ultima lezione sulla creazione di un'app Android per interagire con Chromecast, celebre dongle di Google: ecco come riprodurre i nostri file video.
Ultima lezione sulla creazione di un'app Android per interagire con Chromecast, celebre dongle di Google: ecco come riprodurre i nostri file video.
Link copiato negli appunti

Con la lezione precedente, abbiamo spiegato l'impostazione del nostro lettore multimediale fino all'inizializzazione del RemoteMediaPlayer. Qui ne completeremo l'illustrazione soffermandoci particolarmente su due fattori: gestione della chiusura dell'applicazione - facendo caso in particolare alla pulizia di tutti gli oggetti attivati - e controllo dell'esecuzione.

Chiusura e riconnessione

Visto che in questo caso - a differenza di molte altre situazioni - ci troviamo a fare interagire la nostra app Android con un dispositivo esterno, i loro funzionamenti vanno sincronizzati. Per gestire correttamente la fase di chiusura, predisponiamo un metodo, chiamato stopApplication in cui dovremo prima interrompere l'applicazione Cast, e poi disconnetterci dai Google Play Services:

private void stopApplication() {
        if( googleApiClient != null ) {
            if(started) {
                try {
                    Cast.CastApi.stopApplication(googleApiClient);
                    if( mediaPlayer != null ) {
                        Cast.CastApi.removeMessageReceivedCallbacks(googleApiClient, mediaPlayer.getNamespace() );
                        mediaPlayer = null;
                    }
                } catch( IOException e ) {
                }
                started = false;
            }
            if( googleApiClient.isConnected() )
                googleApiClient.disconnect();
            googleApiClient = null;
        }
        selectedDevice = null;
        loaded = false;
        if (prevButton!=null)
            prevButton.setImageResource(android.R.drawable.ic_media_play);
    }

Invocheremo il metodo stopApplication nei seguenti casi:

  • nel metodo onDestroy che chiude il ciclo di vita dell'Activity;
  • nel metodo onRouteUnselected del MediaRouterCallback, che risponde alla disconnessione da Chromecast operata tramite il CastButton;
  • in onConnectionFailed, invocato quando fallisce la nostra connessione ai Google Play Services tramite un oggetto GoogleApiClient. In questo caso procederemo alla pulizia dei rimanenti oggetti eventualmente attivati;
  • in un altro metodo da noi creato, reconnect, che serve a gestire le riconnessioni al dispositivo Chromecast qualora la connessione venga interrotta:
    private void reconnect(Bundle bundle) {
            if( ( bundle != null ) && bundle.getBoolean( Cast.EXTRA_APP_NO_LONGER_RUNNING ) ) {
                stopApplication();
            } else {
                try {
                    Cast.CastApi.setMessageReceivedCallbacks(googleApiClient, mediaPlayer.getNamespace(), mediaPlayer);
                } catch( IOException e ) {
                    // eccezione IO
                } catch( Exception e ) {
                    // eccezione generica
                }
            }
        }

Gestione della riproduzione video

Siamo finalmente pronti per visualizzare i nostri video. Ogni riga presente nella ListView dispone di un ImageButton che, inizialmente, mostra il simbolo Play, ma una volta attivato mostrerà l'icona Pause. Le casistiche che dovremo gestire sono essenzialmente quattro:

  • avvio di un video mentre non c'è niente in esecuzione;
  • messa in pausa del video in esecuzione;
  • riavvio di un video messo in pausa;
  • cambio del video avviando una nuova riproduzione mentre ce n'era già un'altra in pausa o in esecuzione.

Tutto ciò avviene nel nostro metodo playVideo, che viene invocato ad ogni click su un pulsante della ListView:

public void playVideo(View v) {
        int position = listView.getPositionForView(v);
        String filename = adapter.getItem(position);
        ImageButton btn = (ImageButton) v;
        if(!loaded)
            startVideo(filename, (ImageButton) v);
        else
        {
            if (position != selectedPosition)
            {
                //selezionato un video diverso dal precedente
                btn.setImageResource(android.R.drawable.ic_media_pause);
                if (prevButton!=null)
                {
                    prevButton.setImageResource(android.R.drawable.ic_media_play);
                }
                startVideo(filename, (ImageButton) v);
            }
            else {
                // rimaniamo sullo stesso video
                if (playing) {
                    // andiamo in pausa
                    mediaPlayer.pause(googleApiClient);
                    btn.setImageResource(android.R.drawable.ic_media_play);
                } else {
                    // fine pausa
                    mediaPlayer.play(googleApiClient);
                    btn.setImageResource(android.R.drawable.ic_media_pause);
                }
            }
        }
        selectedPosition = position;
        prevButton = btn;
    }

La sua logica è costruita su una rete di costrutti if...else in cui sfruttiamo i metodi play e pause del RemoteMediaPlayer - ognuno dei quali richiede un riferimento all'oggetto GoogleApiClient - per avviare e mettere in pausa un video. La prima informazione che dobbiamo ricavare è la riga della ListView in cui si trova il pulsante che abbiamo cliccato. Come si può osservare nelle ultime due righe del metodo, questa informazione viene salvata ad ogni esecuzione di playVideo e con essa anche il riferimento all'ultimo pulsante interessato: tutto ciò tornerà utile nelle future interazioni per capire se il nuovo comando che impartiamo si riferisce allo stesso video o ad un altro. Tutti gli if coinvolti serviranno essenzialmente per capire se un'eventuale riproduzione in corso deve essere interrotta o ripresa, e se si deve avviare un nuovo video.

Nei casi in cui viene avviato un video da zero, chiamiamo in causa un altro nostro metodo, startVideo:

private void startVideo(String filename, final ImageButton btn) {
        MediaMetadata mediaMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
        String video_url = createUrl(filename);
        mediaMetadata.putString( MediaMetadata.KEY_TITLE, "In esecuzione " + filename + "...");
        MediaInfo mediaInfo = new MediaInfo.Builder(video_url)
                .setContentType(getString(R.string.media_type ))
                .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
                .setMetadata(mediaMetadata)
                .build();
         mediaPlayer.load(googleApiClient, mediaInfo, true)
                .setResultCallback(new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
                    @Override
                    public void onResult(RemoteMediaPlayer.MediaChannelResult mediaChannelResult) {
                            loaded = true;
                            btn.setImageResource(android.R.drawable.ic_media_pause);
                    }
                });
    }

Principalmente, startVideo si occupa di avviare la riproduzione tramite il metodo load del RemoteMediaPlayer, ma prima di ciò è necessario raccogliere alcune informazioni ed includerle in due oggetti. In MediaMetadata vengono conservati i dati più generali sul video, come la tipologia ed una stringa che apparirà sul televisore durante il caricamento del contenuto. L'oggetto MediaInfo, invece, contiene informazioni più tecniche come il tipo di riproduzione da effettuare, il formato del file e l'URL dal quale potrà essere reperito. Il Listener che rappresenta la conclusione del caricamento vedrà nel suo metodo onResult l'impostazione a true della variabile loaded che sfrutteremo in playVideo, nonchè l'assegnamento del simbolo Pause all'ImageButton cliccato.

Conclusioni

Il lettore multimediale qui presentato rappresenta un primo esempio significativo, molto utile per iniziare a sviluppare le prime app per Chromecast. Ovviamente, però, ci sono ancora moltissimi aspetti interessanti che possono essere approfonditi: si possono infatti gestire interazioni di ogni genere (non solo la riproduzione di video), e predisporre reazioni a qualsiasi tipologia di evento. Inoltre, è possibile utilizzare gli altri tipi di applicazioni Receiver citati nelle lezioni precedenti: Style Media Receiver e Custom Media Receiver. A proposito di questo ultimo punto, va ricordato che per farne uso sarà necessario registrare l'app sulla Google Cast SDK Developer Console per la cui registrazione Mountain View richiede un contributo pari a 5 dollari.

Ti consigliamo anche