Skip to content

Commit

Permalink
add auto switch fullscreen feature, release 1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
linsea committed Jan 30, 2016
1 parent 498d51b commit ada0b5b
Show file tree
Hide file tree
Showing 7 changed files with 257 additions and 14 deletions.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[中文版说明请点击这里](http://my.oschina.net/u/1403288/blog/522278)

UniversalVideoView is a Android widget helps playing video easier, which is similar with the Android system native `VideoView`,
but with more Media Controller customization.
but providing more customization feature: fitXY or keeping aspect ratio fullscreen videoView, auto switch to fullscreen on landscape mode, customised control UI...

![Sample Screenshot 1](./screenshot/screen1.png)
![Sample Screenshot 2](./screenshot/screen2.png)
Expand All @@ -15,7 +15,7 @@ but with more Media Controller customization.
1. add library dependency to your `build.gradle` file.
```groovy
dependencies {
compile 'com.linsea:universalvideoview:1.0.2@aar'
compile 'com.linsea:universalvideoview:1.1.0@aar'
}
```
2. Include the `UniversalVideoView` and `UniversalMediaController` widget in your layout. This should usually be placed
Expand All @@ -32,6 +32,7 @@ but with more Media Controller customization.
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
app:uvv_autoRotation="true"
app:uvv_fitXY="false" />

<com.universalvideoview.UniversalMediaController
Expand Down Expand Up @@ -106,14 +107,17 @@ but with more Media Controller customization.
to prevent the system from recreate the Activity while phone rotation.

# Customization
##`UniversalVideoView` attribute

* `uvv_fitXY` attribute for `UniversalVideoView`, Video scale to fill the VideoView's dimension or keep Aspect Ratio (default) likes Android framework VideoView.
* `uvv_scalable` attribute for `UniversalMediaController`, show or hide the scale button. if you will not play the video in fullscreen.
* `uvv_fitXY`, Video scale to fill the VideoView's dimension or keep Aspect Ratio (default) likes Android framework VideoView.
* `uvv_autoRotation`, auto switch to landscape(fullscreen) or portrait mode according to the orientation sensor.

##`UniversalMediaController` attribute
* `uvv_scalable`, show or hide the scale button. if you will not play the video in fullscreen.

# TODO
* Brightness control on `UniversalMediaController`.
* Volume Control on `UniversalMediaController`.
* Auto switch to full screen on landscape mode.

# License

Expand Down
4 changes: 2 additions & 2 deletions universalvideoview/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ android {
defaultConfig {
minSdkVersion 9
targetSdkVersion 23
versionCode 3
versionName "1.0.2"
versionCode 4
versionName "1.1.0"
}
buildTypes {
release {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/*
* Copyright (C) 2015 Author <dictfb#gmail.com>
*
* 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.universalvideoview;

import android.content.Context;
import android.content.pm.ActivityInfo;
import android.hardware.SensorManager;
import android.util.Log;
import android.view.OrientationEventListener;


public class OrientationDetector {

private static final String TAG = "OrientationDetector";
private static final int HOLDING_THRESHOLD = 1500;
private Context context;
private OrientationEventListener orientationEventListener;

private int rotationThreshold = 20;
private long holdingTime = 0;
private long lastCalcTime = 0;
private Direction lastDirection = Direction.PORTRAIT;

private int currentOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;//初始为竖屏

private OrientationChangeListener listener;

public OrientationDetector(Context context) {
this.context = context;
}


public void setOrientationChangeListener(OrientationChangeListener listener) {
this.listener = listener;
}

public void enable() {
if (orientationEventListener == null) {
orientationEventListener = new OrientationEventListener(context, SensorManager.SENSOR_DELAY_UI) {
@Override
public void onOrientationChanged(int orientation) {
Direction currDirection = calcDirection(orientation);
if (currDirection == null) {
return;
}

if (currDirection != lastDirection) {
resetTime();
lastDirection = currDirection;
if (BuildConfig.DEBUG) {
Log.d(TAG, String.format("方向改变, 开始计时, 当前是方向为%s", currDirection));
}
} else {
calcHoldingTime();
if (holdingTime > HOLDING_THRESHOLD) {
if (currDirection == Direction.LANDSCAPE) {
if (currentOrientation != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
Log.d(TAG, "switch to SCREEN_ORIENTATION_LANDSCAPE");
currentOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
if (listener != null) {
listener.onOrientationChanged(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, currDirection);
}
}

} else if (currDirection == Direction.PORTRAIT) {
if (currentOrientation != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
Log.d(TAG, "switch to SCREEN_ORIENTATION_PORTRAIT");
currentOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
if (listener != null) {
listener.onOrientationChanged(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, currDirection);
}
}

} else if (currDirection == Direction.REVERSE_PORTRAIT) {
if (currentOrientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT) {
Log.d(TAG, "switch to SCREEN_ORIENTATION_REVERSE_PORTRAIT");
currentOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
if (listener != null) {
listener.onOrientationChanged(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, currDirection);
}
}

} else if (currDirection == Direction.REVERSE_LANDSCAPE) {
if (currentOrientation != ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE) {
Log.d(TAG, "switch to SCREEN_ORIENTATION_REVERSE_LANDSCAPE");
currentOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
if (listener != null) {
listener.onOrientationChanged(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE, currDirection);
}
}

}

}
}

}
};
}

orientationEventListener.enable();
}

private void calcHoldingTime() {
long current = System.currentTimeMillis();
if (lastCalcTime == 0) {
lastCalcTime = current;
}
holdingTime += current - lastCalcTime;
// Log.d(TAG, "calcHoldingTime holdingTime=" + holdingTime);
lastCalcTime = current;
}

private void resetTime() {
holdingTime = lastCalcTime = 0;
}

private Direction calcDirection(int orientation) {
if (orientation <= rotationThreshold
|| orientation >= 360 - rotationThreshold) {
return Direction.PORTRAIT;
} else if (Math.abs(orientation - 180) <= rotationThreshold) {
return Direction.REVERSE_PORTRAIT;
} else if (Math.abs(orientation - 90) <= rotationThreshold) {
return Direction.REVERSE_LANDSCAPE;
} else if (Math.abs(orientation - 270) <= rotationThreshold) {
return Direction.LANDSCAPE;
}
return null;
}


public void setInitialDirection(Direction direction) {
lastDirection = direction;
}

public void disable() {
if (orientationEventListener != null) {
orientationEventListener.disable();
}
}

public void setThresholdDegree(int degree) {
rotationThreshold = degree;
}

public interface OrientationChangeListener {
/***
* @param screenOrientation ActivityInfo.SCREEN_ORIENTATION_PORTRAIT or ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
* or ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE or ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT
* @param direction PORTRAIT or REVERSE_PORTRAIT when screenOrientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
* LANDSCAPE or REVERSE_LANDSCAPE when screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE.
*/
void onOrientationChanged(int screenOrientation, Direction direction);
}


public enum Direction {
PORTRAIT, REVERSE_PORTRAIT, LANDSCAPE, REVERSE_LANDSCAPE
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,9 @@ void updateBackButton() {
mBackButton.setVisibility(mIsFullScreen ? View.VISIBLE : View.INVISIBLE);
}

boolean isFullScreen() {
return mIsFullScreen;
}

private void doPauseResume() {
if (mPlayer.isPlaying()) {
Expand Down Expand Up @@ -709,5 +712,16 @@ public interface MediaPlayerControl {
void closePlayer();//关闭播放视频,使播放器处于idle状态

void setFullscreen(boolean fullscreen);

/***
*
* @param fullscreen
* @param screenOrientation valid only fullscreen=true.values should be one of
* ActivityInfo.SCREEN_ORIENTATION_PORTRAIT,
* ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE,
* ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT,
* ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE
*/
void setFullscreen(boolean fullscreen, int screenOrientation);
}
}
Loading

0 comments on commit ada0b5b

Please sign in to comment.