-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9bcf70c
commit a8395a1
Showing
33 changed files
with
1,736 additions
and
90 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
## react-native-video - ExoPlayer | ||
|
||
This is an Android React Native video component based on ExoPlayer v2. | ||
|
||
> ExoPlayer is an application level media player for Android. It provides an alternative to Android’s MediaPlayer API for playing audio and video both locally and over the Internet. ExoPlayer supports features not currently supported by Android’s MediaPlayer API, including DASH and SmoothStreaming adaptive playbacks. Unlike the MediaPlayer API, ExoPlayer is easy to customize and extend, and can be updated through Play Store application updates. | ||
https://github.com/google/ExoPlayer | ||
|
||
## Benefits over `react-native-video@0.9.0`: | ||
|
||
- Android Video library built by Google, with a lot of support | ||
- Supports DASH, HlS, & SmoothStreaming adaptive streams | ||
- Supports formats such as MP4, M4A, FMP4, WebM, MKV, MP3, Ogg, WAV, MPEG-TS, MPEG-PS, FLV and ADTS (AAC). | ||
- Fewer device specific issues | ||
- Highly customisable | ||
|
||
## ExoPlayer only props | ||
|
||
```javascript | ||
|
||
render() { | ||
return ( | ||
<Video | ||
... | ||
disableFocus={true} // disables audio focus and wake lock (default false) | ||
onAudioBecomingNoisy={this.onAudioBecomingNoisy} // Callback when audio is becoming noisy - should pause video | ||
onAudioFocusChanged={this.onAudioFocusChanged} // Callback when audio focus has been lost - pause if focus has been lost | ||
/> | ||
) | ||
} | ||
|
||
onAudioBecomingNoisy = () => { | ||
this.setState({ pause: true }) | ||
} | ||
|
||
onAudioFocusChanged(event: { hasAudioFocus: boolean }) { | ||
if (!this.state.paused && !event.hasAudioFocus) { | ||
this.setState({ paused: true }) | ||
} | ||
} | ||
``` | ||
|
||
## Unimplemented props | ||
|
||
- `playInBackground={true}` | ||
- `rate={1.0}` | ||
- Expansion file - `source={{ mainVer: 1, patchVer: 0 }}` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
apply plugin: 'com.android.library' | ||
|
||
android { | ||
compileSdkVersion 23 | ||
buildToolsVersion "23.0.1" | ||
|
||
defaultConfig { | ||
minSdkVersion 16 | ||
targetSdkVersion 23 | ||
} | ||
} | ||
|
||
dependencies { | ||
provided 'com.facebook.react:react-native:+' | ||
compile 'com.google.android.exoplayer:exoplayer:r2.1.1' | ||
compile('com.google.android.exoplayer:extension-okhttp:r2.1.1') { | ||
exclude group: 'com.squareup.okhttp3', module: 'okhttp' | ||
} | ||
compile 'com.squareup.okhttp3:okhttp:3.4.2' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
package="com.brentvatne.react"> | ||
</manifest> |
143 changes: 143 additions & 0 deletions
143
android-exoplayer/src/main/java/com/brentvatne/exoplayer/AspectRatioFrameLayout.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
/* | ||
* Copyright (C) 2016 The Android Open Source Project | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package com.brentvatne.exoplayer; | ||
|
||
import android.content.Context; | ||
import android.util.AttributeSet; | ||
import android.widget.FrameLayout; | ||
|
||
/** | ||
* A {@link FrameLayout} that resizes itself to match a specified aspect ratio. | ||
*/ | ||
public final class AspectRatioFrameLayout extends FrameLayout { | ||
|
||
/** | ||
* The {@link FrameLayout} will not resize itself if the fractional difference between its natural | ||
* aspect ratio and the requested aspect ratio falls below this threshold. | ||
* <p> | ||
* This tolerance allows the view to occupy the whole of the screen when the requested aspect | ||
* ratio is very close, but not exactly equal to, the aspect ratio of the screen. This may reduce | ||
* the number of view layers that need to be composited by the underlying system, which can help | ||
* to reduce power consumption. | ||
*/ | ||
private static final float MAX_ASPECT_RATIO_DEFORMATION_FRACTION = 0.01f; | ||
|
||
private float videoAspectRatio; | ||
private @ResizeMode.Mode int resizeMode = ResizeMode.RESIZE_MODE_FIT; | ||
|
||
public AspectRatioFrameLayout(Context context) { | ||
this(context, null); | ||
} | ||
|
||
public AspectRatioFrameLayout(Context context, AttributeSet attrs) { | ||
super(context, attrs); | ||
} | ||
|
||
/** | ||
* Set the aspect ratio that this view should satisfy. | ||
* | ||
* @param widthHeightRatio The width to height ratio. | ||
*/ | ||
public void setAspectRatio(float widthHeightRatio) { | ||
if (this.videoAspectRatio != widthHeightRatio) { | ||
this.videoAspectRatio = widthHeightRatio; | ||
requestLayout(); | ||
} | ||
} | ||
|
||
/** | ||
* Get the aspect ratio that this view should satisfy. | ||
* | ||
* @return widthHeightRatio The width to height ratio. | ||
*/ | ||
public float getAspectRatio() { | ||
return videoAspectRatio; | ||
} | ||
|
||
/** | ||
* Sets the resize mode which can be of value {@link ResizeMode.Mode} | ||
* | ||
* @param resizeMode The resize mode. | ||
*/ | ||
public void setResizeMode(@ResizeMode.Mode int resizeMode) { | ||
if (this.resizeMode != resizeMode) { | ||
this.resizeMode = resizeMode; | ||
requestLayout(); | ||
} | ||
} | ||
|
||
/** | ||
* Gets the resize mode which can be of value {@link ResizeMode.Mode} | ||
* | ||
* @return resizeMode The resize mode. | ||
*/ | ||
public @ResizeMode.Mode int getResizeMode() { | ||
return resizeMode; | ||
} | ||
|
||
@Override | ||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | ||
super.onMeasure(widthMeasureSpec, heightMeasureSpec); | ||
if (videoAspectRatio == 0) { | ||
// Aspect ratio not set. | ||
return; | ||
} | ||
|
||
int measuredWidth = getMeasuredWidth(); | ||
int measuredHeight = getMeasuredHeight(); | ||
int width = measuredWidth; | ||
int height = measuredHeight; | ||
|
||
float viewAspectRatio = (float) measuredWidth / measuredHeight; | ||
float aspectDeformation = videoAspectRatio / viewAspectRatio - 1; | ||
if (Math.abs(aspectDeformation) <= MAX_ASPECT_RATIO_DEFORMATION_FRACTION) { | ||
// We're within the allowed tolerance. | ||
return; | ||
} | ||
|
||
switch (resizeMode) { | ||
case ResizeMode.RESIZE_MODE_FIXED_WIDTH: | ||
height = (int) (measuredWidth / videoAspectRatio); | ||
break; | ||
case ResizeMode.RESIZE_MODE_FIXED_HEIGHT: | ||
width = (int) (measuredHeight * videoAspectRatio); | ||
break; | ||
case ResizeMode.RESIZE_MODE_FILL: | ||
// Do nothing width and height is the same as the view | ||
break; | ||
case ResizeMode.RESIZE_MODE_CENTER_CROP: | ||
width = (int) (measuredHeight * videoAspectRatio); | ||
|
||
// Scale video if it doesn't fill the measuredWidth | ||
if (width < measuredWidth) { | ||
float scaleFactor = (float) measuredWidth / width; | ||
width = (int) (width * scaleFactor); | ||
height = (int) (measuredHeight * scaleFactor); | ||
} | ||
break; | ||
default: | ||
if (aspectDeformation > 0) { | ||
height = (int) (measuredWidth / videoAspectRatio); | ||
} else { | ||
width = (int) (measuredHeight * videoAspectRatio); | ||
} | ||
break; | ||
} | ||
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), | ||
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); | ||
} | ||
|
||
} |
70 changes: 70 additions & 0 deletions
70
android-exoplayer/src/main/java/com/brentvatne/exoplayer/DataSourceUtil.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package com.brentvatne.exoplayer; | ||
|
||
import android.content.Context; | ||
|
||
import com.facebook.react.modules.network.OkHttpClientProvider; | ||
import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSourceFactory; | ||
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.DefaultHttpDataSource; | ||
import com.google.android.exoplayer2.upstream.HttpDataSource; | ||
import com.google.android.exoplayer2.util.Util; | ||
|
||
public class DataSourceUtil { | ||
|
||
private DataSourceUtil() { | ||
} | ||
|
||
private static DataSource.Factory rawDataSourceFactory = null; | ||
private static DataSource.Factory defaultDataSourceFactory = null; | ||
private static String userAgent = null; | ||
|
||
public static void setUserAgent(String userAgent) { | ||
DataSourceUtil.userAgent = userAgent; | ||
} | ||
|
||
public static String getUserAgent(Context context) { | ||
if (userAgent == null) { | ||
userAgent = Util.getUserAgent(context.getApplicationContext(), "ReactNativeVideo"); | ||
} | ||
return userAgent; | ||
} | ||
|
||
public static DataSource.Factory getRawDataSourceFactory(Context context) { | ||
if (rawDataSourceFactory == null) { | ||
rawDataSourceFactory = buildRawDataSourceFactory(context); | ||
} | ||
return rawDataSourceFactory; | ||
} | ||
|
||
public static void setRawDataSourceFactory(DataSource.Factory factory) { | ||
DataSourceUtil.rawDataSourceFactory = factory; | ||
} | ||
|
||
public static DataSource.Factory getDefaultDataSourceFactory(Context context, DefaultBandwidthMeter bandwidthMeter) { | ||
if (defaultDataSourceFactory == null) { | ||
defaultDataSourceFactory = buildDataSourceFactory(context, bandwidthMeter); | ||
} | ||
return defaultDataSourceFactory; | ||
} | ||
|
||
public static void setDefaultDataSourceFactory(DataSource.Factory factory) { | ||
DataSourceUtil.defaultDataSourceFactory = factory; | ||
} | ||
|
||
private static DataSource.Factory buildRawDataSourceFactory(Context context) { | ||
return new RawResourceDataSourceFactory(context.getApplicationContext()); | ||
} | ||
|
||
private static DataSource.Factory buildDataSourceFactory(Context context, DefaultBandwidthMeter bandwidthMeter) { | ||
Context appContext = context.getApplicationContext(); | ||
return new DefaultDataSourceFactory(appContext, bandwidthMeter, | ||
buildHttpDataSourceFactory(appContext, bandwidthMeter)); | ||
} | ||
|
||
private static HttpDataSource.Factory buildHttpDataSourceFactory(Context context, DefaultBandwidthMeter bandwidthMeter) { | ||
return new OkHttpDataSourceFactory(OkHttpClientProvider.getOkHttpClient(), getUserAgent(context), bandwidthMeter); | ||
} | ||
|
||
} |
Oops, something went wrong.