Maak een Android Cardboard 360 Video Viewer

Augmented en virtual reality zijn, hoewel nog relatief nieuw, al snel populair geworden voor apps, ook voor gaming en educatie. Eerder heb ik je laten zien hoe je Cardboard kunt installeren met behulp van de Android SDK en hoe je een panoramische afbeeldingsviewer kunt maken. Dit bericht laat je zien hoe je 360-graden video gebruikt in je apps.


Opstelling

Voordat je begint met het bouwen van je videoviewerapp, moet je de Cardboard Android SDK naar je computer klonen via Git. U kunt hiervoor instructies vinden in het vorige artikel van deze serie.

Maak voor ons voorbeeld een nieuw Android-project met een minimale SDK van API 19 (KitKat) en gebruik de Lege activiteit sjabloon.

Zodra uw basisproject is aangemaakt, moet u het kopiëren gemeenschappelijk, commonwidget en videowidget mappen van de Cardboard-SDK naar de hoofdmap van uw project. Zodra deze mappen zijn verplaatst, moet u ze als modules in uw project opnemen door uw settings.gradle bestand om eruit te zien als het volgende fragment. 

include ': app', ": common", "commonwidget", "videowidget"

Voeg ten slotte deze en andere vereiste bibliotheken toe aan uw project door de volgende regels toe te voegen aan uw app module build.gradle bestand onder de afhankelijkheden knooppunt.

dependencies compile 'com.android.support:appcompat-v7:25.0.0' compileer project (': common') compileer project (': commonwidget') compileer project (': videowidget') compileer 'com.google.android. exoplayer: exoplayer: r1.5.10 'compile' com.google.protobuf.nano: protobuf-javanano: 3.0.0-alpha-7 '

U zult merken dat we de Protocolbufferbibliotheek van Google hebben toegevoegd, waarmee u runtime-bronnen op het apparaat kunt beheren, en ExoPlayer, een bibliotheek die door Google is gemaakt en die de VrVideoView component is gebouwd op. Beide bibliotheken zijn vereist voor de Cardboard SDK om te kunnen functioneren, en het is je misschien al opgevallen dat de gebruikte ExoPlayer-versie afkomstig is uit de eerste en niet uit de tweede en dus conflicten kan veroorzaken als je ExoPlayer v2 gebruikt in je eigen projecten.

Vervolgens willen we onze updaten activity_main.xml bestand voor ons voorbeeldproject om een VrVideoView, een SeekBar, en een Knop waar we later mee zullen werken.

    

Als u klaar bent met het instellen van de Cardboard-bibliotheken en de lay-out hebt gemaakt die we gaan gebruiken, is het tijd om naar de Java-code te springen.

Werken met karton en VR-video

Voordat we kunnen beginnen met het schrijven van alle code die de afspeelstatus, positie en laden in je 360 ​​videobestand regelt, moeten we de bron van onze video bepalen. Voor deze zelfstudie maken we eenvoudig een middelen map onder de hoofddirectory en plaats daar een 360 ° -video. Hoewel er online een paar bronnen voor 360 video's zijn, heb ik een korte video in het publieke domein opgenomen van Sea World die een zeeschildpad terugbrengt naar de oceaan in het bijbehorende GitHub-project voor deze zelfstudie. 

Initialiseren en structureren

Nu je een videobestand hebt om te spelen, open je je Hoofdactiviteit klasse.

U moet eerst het. Declareren en initialiseren Uitzicht items die worden gedefinieerd door het lay-outbestand, evenals twee boolean waarden om gemuteerde en afspeel- / pauzetoestand bij te houden. Daarnaast zullen we een plaatsen OnClickListener op ons volume Knop voorwerp.

openbare klasse MainActivity breidt AppCompatActivity uit private VrVideoView mVrVideoView; privé SeekBar mSeekBar; private Button mVolumeButton; private boolean mIsPaused; private boolean mIsMuted; @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); initViews ();  private void initViews () mVrVideoView = (VrVideoView) findViewById (R.id.video_view); mSeekBar = (SeekBar) findViewById (R.id.seek_bar); mVolumeButton = (Button) findViewById (R.id.btn_volume); mVolumeButton.setOnClickListener (nieuwe View.OnClickListener () @Override public void onClick (View view) onVolumeToggleClicked (););  public void playPause ()  public void onVolumeToggleClicked () 

Maak vervolgens een nieuwe innerlijke klasse die zich uitstrekt VrVideoEventListener. Deze klasse heeft vijf methoden die we kunnen implementeren voor onze eenvoudige videoviewer.

private class ActivityEventListener breidt VrVideoEventListener uit @Override public void onLoadSuccess () super.onLoadSuccess ();  @Override public void onLoadError (String errorMessage) super.onLoadError (errorMessage);  @Override public void onClick () super.onClick ();  @Override public void onNewFrame () super.onNewFrame ();  @Override public void onCompletion () super.onCompletion (); 

Je zult ook moeten implementeren SeekBar.OnSeekBarChangeListener in je klas en maak de methodestubs voor die interface.

openbare klasse MainActivity breidt AppCompatActivity implementeert SeekBar.OnSeekBarChangeListener ... public void onPlayPausePressed ()  public void onVolumeToggleClicked ()  @Override public void onProgressChanged (SeekBar seekBar, int i, boolean b) 

Zodra je deze nieuwe innerlijke klasse hebt gemaakt en SeekBar implementatie, koppel ze aan uw VrVideoView en SeekBar, respectievelijk aan het einde van de initViews () methode die hierboven is gedefinieerd.

mVrVideoView.setEventListener (nieuwe ActivityEventListener ()); mSeekBar.setOnSeekBarChangeListener (deze);

Er is nog een deel van de installatie waarvoor moet worden gezorgd. U moet de levenscyclus van de Android-activiteit afhandelen door de. Te ondersteunen onPause (), onResume () en onDestroy () methoden om rendering in de te onderbreken of te hervatten VrVideoView, of om het volledig uit te schakelen. U zult ook de pauzestand in deze methoden moeten volgen.

@Override beschermde leegte onPause () super.onPause (); mVrVideoView.pauseRendering (); mIsPaused = true;  @Override beschermde leegte onResume () super.onResume (); mVrVideoView.resumeRendering (); mIsPaused = false;  @Override protected void onDestroy () mVrVideoView.shutdown (); super.onDestroy ();  

Nu de initiële installatie van onze lesgroep is voltooid, kunnen we verder gaan met het interessantere onderwerp: een video laden, het afspelen regelen en de gebruikerservaring aanpassen.

Starten en besturen VrVideoView

Omdat het laden van een 360 ° -video overal van een fractie van een seconde tot enkele seconden kan duren, wilt u het laden van uw video met een achtergrondtaak afhandelen. Laten we beginnen met het maken van een nieuw AsyncTask dat zal een nieuw creëren VrVideoView.Options object, stel het invoertype in dat overeenkomt met de opmaak van onze video's (in het geval van deze zelfstudie, TYPE_MONO), en laad dan onze video van de middelen directory.

class VideoLoaderTask breidt AsyncTask uit @Override protected Boolean doInBackground (Void ... voids) try VrVideoView.Options options = new VrVideoView.Options (); options.inputType = VrVideoView.Options.TYPE_MONO; mVrVideoView.loadVideoFromAsset ("seaturtle.mp4", opties);  catch (IOException e) // uitzondering hanteren retourneren true; 

Ga vervolgens naar je onCreate () methode en maak een nieuw exemplaar van deze taak aan en bel vervolgens execute () om het te starten. Hoewel er nog meer moet worden gedaan om deze taak op de juiste manier te onderhouden, zullen we deze eenvoudig ter plekke in deze methode gebruiken voor eenvoud en geen zorgen te maken over AsyncTask levenscyclus overwegingen.

VideoLoaderTask mBackgroundVideoLoaderTask = new VideoLoaderTask (); mBackgroundVideoLoaderTask.execute ();

Op dit punt zou u uw applicatie moeten kunnen uitvoeren en de 360 ​​° -video kunnen bekijken in de videoweergave van Cardboard. Nu dat werkt, laten we wat hulpprogramma toevoegen voor onze gebruiker. Ga terug naar de ActivityEventListener object dat u eerder in deze zelfstudie hebt gemaakt, omdat we een aantal methoden willen uitwerken. Wanneer de video is geladen, moeten we de maximumwaarde voor onze video instellen SeekBar, en houd ook de afspeel- / pauzestand bij van onze video.

@Override public void onLoadSuccess () super.onLoadSuccess (); mSeekBar.setMax ((int) mVrVideoView.getDuration ()); mIsPaused = false; 

Terwijl de video wordt afgespeeld, updaten we dat SeekBar door onNewFrame (), en reset de video naar de beginpositie in ter afronding(). Ten slotte, in bij klikken(), we zullen onze play / pause-schakelfunctie activeren.

@Override public void onClick () playPause ();  @Override public void onNewFrame () super.onNewFrame (); mSeekBar.setProgress ((int) mVrVideoView.getCurrentPosition ());  @Override public void onCompletion () // Start de video opnieuw, zodat deze lus mVrVideoView.seekTo (0); 

Tijdens het updaten van onze SeekBar op basis van het afspelen is belangrijk, we willen de gebruiker ook toestaan ​​te wijzigen waar ze zich in de video bevinden door interactie met de SeekBar. We kunnen dit doen met behulp van de SeekBar.OnSeekBarChangeListener interface die we eerder hebben geïmplementeerd.

@Override public void onProgressChanged (SeekBar seekBar, int progress, boolean fromUser) if (fromUser) mVrVideoView.seekTo (progress); 

Om onze te vervolledigen VrVideoView besturingselementen, moeten we de afspeel- / pauze- en volumeknop-methoden implementeren.

public void playPause () if (mIsPaused) mVrVideoView.playVideo ();  else mVrVideoView.pauseVideo ();  mIsPaused =! mIsPaused;  public void onVolumeToggleClicked () mIsMuted =! mIsMuted; mVrVideoView.setVolume (mIsMuted? 0.0f: 1.0f); 

Op dit moment moet u een volledig werkende en interactieve 360-videospeler hebben die in uw app werkt. 

Als u echter uw apparaat draait, merkt u mogelijk het ongewenste gedrag van de video volledig opnieuw op. We kunnen dit oplossen door met Android's te werken onSaveInstanceState () en onRestoreInstanceState () om de staat van ons op te slaan en opnieuw in te stellen VrVideoView.

private static final String STATE_PROGRESS = "state_progress"; private static final String STATE_DURATION = "state_duration"; @Override protected void onSaveInstanceState (Bundle outState) outState.putLong (STATE_PROGRESS, mVrVideoView.getCurrentPosition ()); outState.putLong (STATE_DURATION, mVrVideoView.getDuration ()); super.onSaveInstanceState (outState);  @Override beschermde ongeldig opRestoreInstanceState (Bundel savedInstanceState) super.onRestoreInstanceState (savedInstanceState); lange voortgang = savedInstanceState.getLong (STATE_PROGRESS); mVrVideoView.seekTo (vooruitgang); mSeekBar.setMax ((int) savedInstanceState.getLong (STATE_DURATION)); mSeekBar.setProgress ((int) voortgang); 

Wanneer het apparaat wordt geroteerd, moet uw video terugkeren naar de oorspronkelijke positie en kan uw gebruiker doorgaan met zijn ononderbroken ervaring.

Conclusie

Hoewel er een paar kleine details zijn die moeten worden afgehandeld om de VrVideoView van de Cardboard SDK te gebruiken, worden de moeilijke delen, zoals werkelijke weergave en optimalisatie, voor u behandeld door een component die eenvoudig te implementeren is. 

Je zou nu in staat moeten zijn 360-video's toe te voegen aan je media-apps, zodat je gebruikers een interessante functie krijgen die hun ervaring verrijkt. In de volgende zelfstudie van deze serie zullen we ons concentreren op de nieuwe VR-ervaring van Google genaamd Daydream en hoe je de gepaarde controller met je apps kunt gebruiken.

Bekijk in de tussentijd een aantal van onze andere zelfstudies over Android virtual reality en augmented reality!