1
0
forked from cgvr/DeltaVR

deltavr multiplayer 2.0

This commit is contained in:
Toomas Tamm
2023-05-08 15:56:10 +03:00
parent 978809a002
commit 07b9b9e2f4
10937 changed files with 2968397 additions and 1521012 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 436b6a9e384de9446bb85b969e0d6eb9
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 49c334cc948b2724ea9662d357cb78ae
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 83e0182c75aad7d43b7e8288b169db41
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3a259fc639d42744c9aa779ebf0b97c5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9796cce996f141b41911e7efe0bad759
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,22 @@
Facebook 360 Audio Terms
These Facebook 360 Audio Terms (“Terms”) govern your use of the Facebook 360 Audio Engine software (including any updates, upgrades and/or new versions thereof that are made available to you) (collectively, the “Software”). By accessing or using the Software, you agree to the Terms.
Last updated on 11 August 2017
1. Subject to these Terms, Facebook hereby grants to you a worldwide, non-exclusive, no-charge, non-transferable, non-sublicenseable, royalty-free copyright license to (a) use and reproduce the Software in object code format for inclusion in your applications, content, games, and demos (collectively referred to as “Developer Content”), and (b) distribute the Software solely as incorporated in your Developer Content.
2. You agree:
a) Not to copy or use the Software for any purpose except as expressly permitted by these Terms;
b) Not to modify, disassemble, decompile or otherwise reverse engineer the Software;
c) To ensure that your employees, agents and other parties under your control who will use the Software do so in accordance with these Terms and are accordingly notified of the same;
d) Not to permit or facilitate the use of the Software in any manner which would constitute a breach of these Terms; and
e) Not to place or distribute the Software (except as incorporated in your Developer Content) on any website, File Transfer Protocol server or similar location without the express prior written consent of Facebook.
3. You will use reasonable efforts to include in the Developer Content any logo, audio badge and/or other branding for the Software that Facebook may reasonably request, and Facebook hereby grants you a limited, non-exclusive, non-transferable, non-sublicenseable license to use such branding assets solely in the manner Facebook requests.
4. Facebook may make changes to these Terms at any time by notifying you in writing (including email) describing the changes made. Any such changes will become effective, and will be deemed accepted by you, thirty (30) days following your receipt of notice (except any changes Facebook notifies you are required by law, which will become effective immediately) (the “Notice Period”). If you do not agree to any or all changes to these Terms, you must cease use of the Software during the Notice Period as to any prospective Developer Content, which will be your sole and exclusive remedy. Any then-existing Developer Content will continue to be governed by the then-prior version of these Terms. You agree that your continued use of the Software after the Notice Period constitutes your agreement to the applicable changes to these Terms.
5. Facebook reserves the right to terminate these Terms and all your rights hereunder in the event: (a) you materially breach these Terms and fail to cure such breach within ten (10) business days after notice of breach from Facebook; (b) a claim is threatened or made by a third party that the Developer Content infringes its intellectual property or proprietary rights; (c) the Developer Content violates or infringes applicable law; or (d) Facebook believes in good faith that your use of the Software poses a risk to, or could adversely impact, Facebooks or its affiliates products or business. Termination pursuant to this Section 5 shall be effective: (i) immediately upon notice from Facebook for termination under the foregoing subsections (b) or (c), and (ii) within thirty (30) days after notice from Facebook for termination under subsection (d). Termination under subsection (d) shall be effective as to any prospective Developer Content but not as to any then-existing Developer Content, provided, however, that you shall use commercially reasonable efforts to create and distribute new versions of the Developer Content during such thirty (30) day notice period which does not utilize the Software (“New Versions”) and encourage end users to replace the Developer Content with the New Versions.
6. You may not assign any rights or obligations under these Terms without the advance written consent of Facebook, which may be withheld in its sole discretion; provided, however, that you may, without such consent, assign these Terms in connection with the transfer or sale of all or substantially all of your business or assets related to these Terms, or in the event of a merger, consolidation, change in control or other similar transaction (a “Change of Control”). In the event of a Change of Control: (a) you will give written notice to Facebook within thirty (30) days after the Change of Control; and (b) Facebook may immediately terminate rights or obligations under these Terms any time between the Change of Control and thirty (30) days after it receives that written notice. Facebook may assign its rights or obligations under these Terms in its sole discretion.
7. Your remedies under these Terms shall be limited to the right to collect money damages, if any, and you hereby waive your right to injunctive or other equitable relief.
8. Your use of third-party materials included in the Software may be subject to other terms and conditions typically found in separate third-party license agreements or “READ ME” files included with such third-party materials. To the extent such other terms and conditions conflict with these Terms, the former will control with respect to the applicable third-party materials.
9. Facebook may include in the Software additional content (e.g., samples) for demonstration, references or other specific purposes. Such content will be clearly marked in the Software and is subject to any included terms and conditions.
10. If you are accepting these terms on behalf of a third party, you represent and warrant that you have the authority as agent to such party to use such feature on their behalf and bind such party to these terms.
11. You are solely responsible for ensuring that your use of the Software complies with the Facebook Platform Policy located at https://developers.facebook.com/policy/.
12. The Software is part of “Facebook” under Facebooks Statement of Rights and Responsibilities (https://www.facebook.com/legal/terms, the “SRR”), and your use of the Software is deemed part of your use of, and actions on, “Facebook.” In the event of any express conflict between these Terms and the SRR, these Terms will govern solely with respect to your use of the Software and solely to the extent of the conflict. Facebook reserves the right to monitor or audit your compliance with these Terms and to update these Terms from time to time as described above.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 4d41527e8defd4278aa630380a98e8d5
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,141 @@
THE FOLLOWING SETS FORTH ATTRIBUTION NOTICES FOR THIRD PARTY SOFTWARE THAT MAY BE CONTAINED IN PORTIONS OF AUDIO360
-----
The Audio360 software may use libsamplerate under the BSD open source license, available from http://www.mega-nerd.com/SRC/. libsamplerate contains the following license and notice below:
Copyright (c) 2012-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The Audio360 software may use Wavpack, available from http://www.wavpack.com. Wavpack contains the following license and notice below:
Copyright (c) 1998 - 2016 David Bryant
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Conifer Software nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The Audio360 software may use libopus, available from http://opus-codec.org/. libopus contains the following license and notice below:
Copyright 2001-2011 Xiph.Org, Skype Limited, Octasic,
Jean-Marc Valin, Timothy B. Terriberry,
CSIRO, Gregory Maxwell, Mark Borgerding,
Erik de Castro Lopo
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of Internet Society, IETF or IETF Trust, nor the
names of specific contributors, may be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Opus is subject to the royalty-free patent licenses which are
specified at:
Xiph.Org Foundation:
https://datatracker.ietf.org/ipr/1524/
Microsoft Corporation:
https://datatracker.ietf.org/ipr/1914/
Broadcom Corporation:
https://datatracker.ietf.org/ipr/1526/
The Audio360 software may use PortAudio, available from http://www.portaudio.com. PortAudio contains the following license and notice below:
PortAudio Portable Real-Time Audio Library
Latest version at: http://www.portaudio.com
Copyright (c) 1999-2008 Phil Burk and Ross Bencina
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
The text above constitutes the entire PortAudio license; however,
the PortAudio community also makes the following non-binding requests:
Any person wishing to distribute modifications to the Software is
requested to send the modifications to the original developer so that
they can be incorporated into the canonical version. It is also
requested that these non-binding requests be included along with the
license above.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 1ed4d8069bb483a4ea222be6e17e75b6
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
fileFormatVersion: 2
guid: 6f1932f9a85d347a685f96d6643ac091
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: x86_64
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,87 @@
fileFormatVersion: 2
guid: 0fc24de97752a4f81b61159248da7281
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
isPreloaded: 0
isOverridable: 0
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux: 1
Exclude Linux64: 1
Exclude LinuxUniversal: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux
second:
enabled: 0
settings:
CPU: x86
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: x86_64
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d030c8ccce132694ba66efc312b20050
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0dd29019dbce46e4eb76ff5daf345fbd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 437e818a5df520a41b592b18a218b93e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ef869dfc5cfdad6458d54363c87e5982
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,590 @@
/************************************************************************************
Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
************************************************************************************/
package com.oculus.videoplayer;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.storage.OnObbStateChangeListener;
import android.os.storage.StorageManager;
//import android.support.annotation.Nullable;
import android.util.Log;
import android.view.Surface;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.C.ContentType;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.ExoPlaybackException;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.PlaybackPreparer;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.RenderersFactory;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.audio.AudioRendererEventListener;
import com.google.android.exoplayer2.audio.AudioSink;
import com.google.android.exoplayer2.drm.DefaultDrmSessionManager;
import com.google.android.exoplayer2.drm.DrmSessionManager;
import com.google.android.exoplayer2.drm.FrameworkMediaCrypto;
import com.google.android.exoplayer2.drm.FrameworkMediaDrm;
import com.google.android.exoplayer2.drm.HttpMediaDrmCallback;
import com.google.android.exoplayer2.drm.UnsupportedDrmException;
import com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.DecoderInitializationException;
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector;
import com.google.android.exoplayer2.mediacodec.MediaCodecUtil.DecoderQueryException;
import com.google.android.exoplayer2.metadata.MetadataOutput;
import com.google.android.exoplayer2.source.BehindLiveWindowException;
import com.google.android.exoplayer2.source.ConcatenatingMediaSource;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.source.TrackGroupArray;
import com.google.android.exoplayer2.source.ads.AdsLoader;
import com.google.android.exoplayer2.source.ads.AdsMediaSource;
import com.google.android.exoplayer2.source.dash.DashChunkSource;
import com.google.android.exoplayer2.source.dash.DefaultDashChunkSource;
import com.google.android.exoplayer2.source.dash.DashMediaSource;
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
import com.google.android.exoplayer2.source.smoothstreaming.DefaultSsChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.SsChunkSource;
import com.google.android.exoplayer2.source.smoothstreaming.SsMediaSource;
import com.google.android.exoplayer2.text.TextOutput;
import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection;
import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo;
import com.google.android.exoplayer2.trackselection.RandomTrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelection;
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
import com.google.android.exoplayer2.upstream.BandwidthMeter;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
import com.google.android.exoplayer2.upstream.FileDataSourceFactory;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.cache.Cache;
import com.google.android.exoplayer2.upstream.cache.CacheDataSource;
import com.google.android.exoplayer2.upstream.cache.CacheDataSourceFactory;
import com.google.android.exoplayer2.upstream.cache.NoOpCacheEvictor;
import com.google.android.exoplayer2.upstream.cache.SimpleCache;
import com.google.android.exoplayer2.util.ErrorMessageProvider;
import com.google.android.exoplayer2.util.EventLogger;
import com.google.android.exoplayer2.util.Util;
import com.google.android.exoplayer2.video.MediaCodecVideoRenderer;
import com.google.android.exoplayer2.video.VideoListener;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
import com.twobigears.audio360.AudioEngine;
import com.twobigears.audio360.ChannelMap;
import com.twobigears.audio360.SpatDecoderQueue;
import com.twobigears.audio360.TBQuat;
import com.twobigears.audio360exo2.Audio360Sink;
import com.twobigears.audio360exo2.OpusRenderer;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.Math;
import java.lang.System;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.CookiePolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
/**
* Created by trevordasch on 9/19/2018.
*/
public class NativeVideoPlayer
{
private static final String TAG = "NativeVideoPlayer"
;
static AudioEngine engine;
static SpatDecoderQueue spat;
static final float SAMPLE_RATE = 48000.f;
static final int BUFFER_SIZE = 1024;
static final int QUEUE_SIZE_IN_SAMPLES = 40960;
static SimpleExoPlayer exoPlayer;
static AudioSink audio360Sink;
static File downloadDirectory;
static Cache downloadCache;
static FrameworkMediaDrm mediaDrm;
static Handler handler;
static volatile boolean isPlaying;
static volatile int currentPlaybackState;
static volatile int stereoMode = -1;
static volatile int width;
static volatile int height;
static volatile long duration;
static volatile long lastPlaybackPosition;
static volatile long lastPlaybackUpdateTime;
static volatile float lastPlaybackSpeed;
private static void updatePlaybackState() {
duration = exoPlayer.getDuration();
lastPlaybackPosition = exoPlayer.getCurrentPosition();
lastPlaybackSpeed = isPlaying ? exoPlayer.getPlaybackParameters().speed : 0;
lastPlaybackUpdateTime = System.currentTimeMillis();
Format format = exoPlayer.getVideoFormat();
if (format != null) {
stereoMode = format.stereoMode;
width = format.width;
height = format.height;
}
else {
stereoMode = -1;
width = 0;
height = 0;
}
}
private static Handler getHandler()
{
if (handler == null)
{
handler = new Handler(Looper.getMainLooper());
}
return handler;
}
private static class CustomRenderersFactory extends DefaultRenderersFactory {
private Context myContext;
private long myAllowedVideoJoiningTimeMs = 5000;
public CustomRenderersFactory(Context context) {
super(context);
this.myContext = context;
}
@Override
public DefaultRenderersFactory setAllowedVideoJoiningTimeMs(long allowedVideoJoiningTimeMs) {
super.setAllowedVideoJoiningTimeMs(allowedVideoJoiningTimeMs);
myAllowedVideoJoiningTimeMs = allowedVideoJoiningTimeMs;
return this;
}
@Override
public Renderer[] createRenderers(
Handler eventHandler,
VideoRendererEventListener videoRendererEventListener,
AudioRendererEventListener audioRendererEventListener,
TextOutput textRendererOutput,
MetadataOutput metadataRendererOutput,
/*@Nullable*/ DrmSessionManager<FrameworkMediaCrypto> drmSessionManager) {
Renderer[] renderers = super.createRenderers(
eventHandler,
videoRendererEventListener,
audioRendererEventListener,
textRendererOutput,
metadataRendererOutput,
drmSessionManager);
ArrayList<Renderer> rendererList = new ArrayList<Renderer>(Arrays.asList(renderers));
// The output latency of the engine can be used to compensate for sync
double latency = engine.getOutputLatencyMs();
// Audio: opus codec with the spatial audio engine
// TBE_8_2 implies 10 channels of audio (8 channels of spatial audio, 2 channels of head-locked)
audio360Sink = new Audio360Sink(spat, ChannelMap.TBE_8_2, latency);
final OpusRenderer audioRenderer = new OpusRenderer(audio360Sink);
rendererList.add(audioRenderer);
renderers = rendererList.toArray(renderers);
return renderers;
}
}
private static File getDownloadDirectory(Context context) {
if (downloadDirectory == null) {
downloadDirectory = context.getExternalFilesDir(null);
if (downloadDirectory == null) {
downloadDirectory = context.getFilesDir();
}
}
return downloadDirectory;
}
private static synchronized Cache getDownloadCache(Context context) {
if (downloadCache == null) {
File downloadContentDirectory = new File(getDownloadDirectory(context), "downloads");
downloadCache = new SimpleCache(downloadContentDirectory, new NoOpCacheEvictor());
}
return downloadCache;
}
private static CacheDataSourceFactory buildReadOnlyCacheDataSource(
DefaultDataSourceFactory upstreamFactory, Cache cache) {
return new CacheDataSourceFactory(
cache,
upstreamFactory,
new FileDataSourceFactory(),
/* cacheWriteDataSinkFactory= */ null,
CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR,
/* eventListener= */ null);
}
/** Returns a {@link DataSource.Factory}. */
public static DataSource.Factory buildDataSourceFactory(Context context) {
DefaultDataSourceFactory upstreamFactory =
new DefaultDataSourceFactory(context, null, buildHttpDataSourceFactory(context));
return buildReadOnlyCacheDataSource(upstreamFactory, getDownloadCache(context));
}
/** Returns a {@link HttpDataSource.Factory}. */
public static HttpDataSource.Factory buildHttpDataSourceFactory(Context context) {
return new DefaultHttpDataSourceFactory(Util.getUserAgent(context, "NativeVideoPlayer"));
}
private static DefaultDrmSessionManager<FrameworkMediaCrypto> buildDrmSessionManagerV18(Context context,
UUID uuid, String licenseUrl, String[] keyRequestPropertiesArray, boolean multiSession)
throws UnsupportedDrmException {
HttpDataSource.Factory licenseDataSourceFactory = buildHttpDataSourceFactory(context);
HttpMediaDrmCallback drmCallback =
new HttpMediaDrmCallback(licenseUrl, licenseDataSourceFactory);
if (keyRequestPropertiesArray != null) {
for (int i = 0; i < keyRequestPropertiesArray.length - 1; i += 2) {
drmCallback.setKeyRequestProperty(keyRequestPropertiesArray[i],
keyRequestPropertiesArray[i + 1]);
}
}
if (mediaDrm != null)
{
mediaDrm.release();
}
mediaDrm = FrameworkMediaDrm.newInstance(uuid);
return new DefaultDrmSessionManager<>(uuid, mediaDrm, drmCallback, null, multiSession);
}
@SuppressWarnings("unchecked")
private static MediaSource buildMediaSource(Context context, Uri uri, /*@Nullable*/ String overrideExtension, DataSource.Factory dataSourceFactory) {
@ContentType int type = Util.inferContentType(uri, overrideExtension);
switch (type) {
case C.TYPE_DASH:
return new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(dataSourceFactory), dataSourceFactory)
.createMediaSource(uri);
case C.TYPE_SS:
return new SsMediaSource.Factory(new DefaultSsChunkSource.Factory(dataSourceFactory), dataSourceFactory)
.createMediaSource(uri);
case C.TYPE_HLS:
return new HlsMediaSource.Factory(dataSourceFactory)
.createMediaSource(uri);
case C.TYPE_OTHER:
return new ExtractorMediaSource.Factory(dataSourceFactory).createMediaSource(uri);
default: {
throw new IllegalStateException("Unsupported type: " + type);
}
}
}
public static void playVideo( final Context context, final String filePath, final String drmLicenseUrl, final Surface surface)
{
// set up exoplayer on main thread
getHandler().post( new Runnable()
{
@Override
public void run()
{
// 1. Create a default TrackSelector
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory =
new AdaptiveTrackSelection.Factory(bandwidthMeter);
DefaultTrackSelector trackSelector =
new DefaultTrackSelector(videoTrackSelectionFactory);
// Produces DataSource instances through which media data is loaded.
DataSource.Factory dataSourceFactory = buildDataSourceFactory(context);
Uri uri = Uri.parse( filePath );
if (filePath.startsWith( "jar:file:" )) {
if (filePath.contains(".apk")) { // APK
uri = new Uri.Builder().scheme( "asset" ).path( filePath.substring( filePath.indexOf( "/assets/" ) + "/assets/".length() ) ).build();
}
else if (filePath.contains(".obb")) { // OBB
String obbPath = filePath.substring(11, filePath.indexOf(".obb") + 4);
StorageManager sm = (StorageManager)context.getSystemService(Context.STORAGE_SERVICE);
if (!sm.isObbMounted(obbPath))
{
sm.mountObb(obbPath, null, new OnObbStateChangeListener() {
@Override
public void onObbStateChange(String path, int state) {
super.onObbStateChange(path, state);
}
});
}
uri = new Uri.Builder().scheme( "file" ).path( sm.getMountedObbPath(obbPath) + filePath.substring(filePath.indexOf(".obb") + 5) ).build();
}
}
// Set up video source if drmLicenseUrl is set
DefaultDrmSessionManager<FrameworkMediaCrypto> drmSessionManager = null;
if (drmLicenseUrl != null && drmLicenseUrl.length() > 0) {
try {
drmSessionManager = buildDrmSessionManagerV18(context,
Util.getDrmUuid("widevine"), drmLicenseUrl, null, false);
} catch (UnsupportedDrmException e) {
Log.e(TAG, "Unsupported DRM!", e);
}
}
// This is the MediaSource representing the media to be played.
MediaSource videoSource = buildMediaSource(context, uri, null, dataSourceFactory);
Log.d(TAG, "Requested play of " +filePath + " uri: "+uri.toString());
// 2. Create the player
//--------------------------------------
//- Audio Engine
if (engine == null)
{
engine = AudioEngine.create(SAMPLE_RATE, BUFFER_SIZE, QUEUE_SIZE_IN_SAMPLES, context);
spat = engine.createSpatDecoderQueue();
engine.start();
}
//--------------------------------------
//- ExoPlayer
// Create our modified ExoPlayer instance
if (exoPlayer != null)
{
exoPlayer.release();
}
exoPlayer = ExoPlayerFactory.newSimpleInstance(context, new CustomRenderersFactory(context), trackSelector, drmSessionManager);
exoPlayer.addListener(new Player.DefaultEventListener() {
@Override
public void onPlayerStateChanged(boolean playWhenReady, int playbackState)
{
isPlaying = playWhenReady && (playbackState == Player.STATE_READY || playbackState == Player.STATE_BUFFERING);
currentPlaybackState = playbackState;
updatePlaybackState();
}
@Override
public void onPlaybackParametersChanged(PlaybackParameters params)
{
updatePlaybackState();
}
@Override
public void onPositionDiscontinuity(int reason)
{
updatePlaybackState();
}
});
exoPlayer.setVideoSurface( surface );
// Prepare the player with the source.
exoPlayer.prepare(videoSource);
exoPlayer.setPlayWhenReady( true );
}
});
}
public static void setLooping(final boolean looping)
{
getHandler().post( new Runnable()
{
@Override
public void run()
{
if ( exoPlayer != null )
{
if ( looping )
{
exoPlayer.setRepeatMode( Player.REPEAT_MODE_ONE );
}
else
{
exoPlayer.setRepeatMode( Player.REPEAT_MODE_OFF );
}
}
}
});
}
public static void stop()
{
getHandler().post( new Runnable()
{
@Override
public void run()
{
if ( exoPlayer != null )
{
exoPlayer.stop();
exoPlayer.release();
exoPlayer = null;
}
if ( mediaDrm != null) {
mediaDrm.release();
mediaDrm = null;
}
if (engine != null)
{
engine.destroySpatDecoderQueue(spat);
engine.delete();
spat = null;
engine = null;
}
}
});
}
public static void pause()
{
getHandler().post( new Runnable()
{
@Override
public void run()
{
if ( exoPlayer != null )
{
exoPlayer.setPlayWhenReady(false);
}
}
});
}
public static void resume()
{
getHandler().post( new Runnable()
{
@Override
public void run()
{
if ( exoPlayer != null )
{
exoPlayer.setPlayWhenReady(true);
}
}
});
}
public static void setPlaybackSpeed(final float speed)
{
getHandler().post( new Runnable()
{
@Override
public void run()
{
if ( exoPlayer != null )
{
PlaybackParameters param = new PlaybackParameters(speed);
exoPlayer.setPlaybackParameters(param);
}
}
});
}
public static void setListenerRotationQuaternion(float x, float y, float z, float w)
{
if (engine != null)
{
engine.setListenerRotation(new TBQuat(x,y,z,w));
}
}
public static boolean getIsPlaying()
{
return isPlaying;
}
public static int getCurrentPlaybackState()
{
return currentPlaybackState;
}
public static long getDuration()
{
return duration;
}
public static int getStereoMode()
{
return stereoMode;
}
public static int getWidth()
{
return width;
}
public static int getHeight()
{
return height;
}
public static long getPlaybackPosition()
{
return Math.max(0, Math.min(duration, lastPlaybackPosition + (long)((System.currentTimeMillis() - lastPlaybackUpdateTime) * lastPlaybackSpeed)));
}
public static void setPlaybackPosition(final long position)
{
getHandler().post( new Runnable()
{
@Override
public void run()
{
if ( exoPlayer != null )
{
Timeline timeline = exoPlayer.getCurrentTimeline();
if ( timeline != null )
{
int windowIndex = timeline.getFirstWindowIndex(false);
long windowPositionUs = position * 1000L;
Timeline.Window tmpWindow = new Timeline.Window();
for(int i = timeline.getFirstWindowIndex(false);
i < timeline.getLastWindowIndex(false); i++)
{
timeline.getWindow(i, tmpWindow);
if (tmpWindow.durationUs > windowPositionUs)
{
break;
}
windowIndex++;
windowPositionUs -= tmpWindow.durationUs;
}
exoPlayer.seekTo(windowIndex, windowPositionUs / 1000L);
}
}
}
});
}
}

View File

@@ -0,0 +1,32 @@
fileFormatVersion: 2
guid: 0d7c62804c0fce54b8d0e82ad854713b
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Android: Android
second:
enabled: 1
settings: {}
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
DefaultValueInitialized: true
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: c178d2dd5c1974842b2c64b78dfc1693
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: ff553a5920330cd4692d8f69f021d55b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,68 @@
Shader "Unlit/Multiview Stereo"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_SrcRectLeft("SrcRectLeft", Vector) = (0,0,1,1)
_SrcRectRight("SrcRectRight", Vector) = (0,0,1,1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
float2 pos : TEXCOORD1;
};
sampler2D _MainTex;
float4 _MainTex_ST;
float4 _SrcRectLeft;
float4 _SrcRectRight;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
float4 srcRect = lerp(_SrcRectLeft, _SrcRectRight, unity_StereoEyeIndex);
o.pos = TRANSFORM_TEX(v.uv, _MainTex);
o.uv = (o.pos * srcRect.zw) + srcRect.xy;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
if (i.pos.x < 0.0 || i.pos.y < 0.0 || i.pos.x > 1.0 || i.pos.y > 1.0)
{
return float4(0,0,0,0);
}
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
Fallback "Unlit/Texture"
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 873aaf52f432945df9937ea75a74c0e7
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant: