初始化

This commit is contained in:
SmallMain
2022-06-25 00:23:03 +08:00
commit ef0589e8e5
2264 changed files with 617829 additions and 0 deletions

View File

@@ -0,0 +1,296 @@
/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.
http://www.cocos2d-x.org
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.
****************************************************************************/
#include "VideoPlayer.h"
#include "base/CCLog.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <unordered_map>
#include <stdlib.h>
#include <jni.h>
#include <string>
#include "platform/CCApplication.h"
#include "platform/android/jni/JniHelper.h"
#include "platform/CCFileUtils.h"
#include "renderer/gfx/Texture2D.h"
//-----------------------------------------------------------------------------------------------------------
static const std::string videoHelperClassName = "org/cocos2dx/lib/Cocos2dxVideoHelper";
USING_NS_CC;
static void executeVideoCallback(int index,int event);
#define QUIT_FULLSCREEN 1000
extern "C" {
void Java_org_cocos2dx_lib_Cocos2dxVideoHelper_nativeExecuteVideoCallback(JNIEnv * env, jobject obj, jint index,jint event) {
executeVideoCallback(index,event);
}
}
int createVideoWidgetJNI()
{
JniMethodInfo t;
int ret = -1;
if (JniHelper::getStaticMethodInfo(t, videoHelperClassName.c_str(), "createVideoWidget", "()I")) {
ret = t.env->CallStaticIntMethod(t.classID, t.methodID);
t.env->DeleteLocalRef(t.classID);
}
return ret;
}
//-----------------------------------------------------------------------------------------------------------
static std::unordered_map<int, VideoPlayer*> s_allVideoPlayers;
static jobject s_jobj = nullptr;
VideoPlayer::VideoPlayer()
: _videoPlayerIndex(-1)
, _fullScreenEnabled(false)
, _fullScreenDirty(false)
, _keepAspectRatioEnabled(false)
, _videoPixels(nullptr)
, _texDataSize(0)
, _maxDataLen(0)
{
_videoPlayerIndex = createVideoWidgetJNI();
s_allVideoPlayers[_videoPlayerIndex] = this;
#if CC_VIDEOPLAYER_DEBUG_DRAW
_debugDrawNode = DrawNode::create();
addChild(_debugDrawNode);
#endif
if(s_jobj == nullptr) {
s_jobj = JniHelper::getEnv()->NewGlobalRef(JniHelper::newObject(videoHelperClassName.c_str()));
}
}
VideoPlayer::~VideoPlayer()
{
s_allVideoPlayers.erase(_videoPlayerIndex);
JniHelper::callStaticVoidMethod(videoHelperClassName, "removeVideoWidget", _videoPlayerIndex);
if (_videoPixels != nullptr) free(_videoPixels);
}
void VideoPlayer::setURL(const std::string& videoUrl)
{
if (videoUrl.find("://") == std::string::npos)
{
_videoURL = FileUtils::getInstance()->fullPathForFilename(videoUrl);
_videoSource = VideoPlayer::Source::FILENAME;
}
else
{
_videoURL = videoUrl;
_videoSource = VideoPlayer::Source::URL;
}
JniHelper::callStaticVoidMethod(videoHelperClassName, "setVideoUrl", _videoPlayerIndex,
(int)_videoSource,_videoURL);
}
void VideoPlayer::VideoPlayer::setFrame(float x, float y, float width, float height)
{
JniHelper::callStaticVoidMethod(videoHelperClassName, "setVideoRect", _videoPlayerIndex,
(int)x, (int)y, (int)width, (int)height);
}
void VideoPlayer::setFullScreenEnabled(bool enabled)
{
if (_fullScreenEnabled != enabled)
{
_fullScreenEnabled = enabled;
JniHelper::callStaticVoidMethod(videoHelperClassName, "setFullScreenEnabled", _videoPlayerIndex, enabled);
}
}
void VideoPlayer::setKeepAspectRatioEnabled(bool enable)
{
if (_keepAspectRatioEnabled != enable)
{
_keepAspectRatioEnabled = enable;
JniHelper::callStaticVoidMethod(videoHelperClassName, "setVideoKeepRatioEnabled", _videoPlayerIndex, enable);
}
}
void VideoPlayer::play()
{
if (! _videoURL.empty())
{
JniHelper::callStaticVoidMethod(videoHelperClassName, "startVideo", _videoPlayerIndex);
}
}
void VideoPlayer::pause()
{
if (! _videoURL.empty())
{
JniHelper::callStaticVoidMethod(videoHelperClassName, "pauseVideo", _videoPlayerIndex);
}
}
void VideoPlayer::stop()
{
if (! _videoURL.empty())
{
JniHelper::callStaticVoidMethod(videoHelperClassName, "stopVideo", _videoPlayerIndex);
}
}
void VideoPlayer::seekTo(float sec)
{
if (! _videoURL.empty())
{
JniHelper::callStaticVoidMethod(videoHelperClassName, "seekVideoTo", _videoPlayerIndex, int(sec * 1000));
}
}
void VideoPlayer::setVisible(bool visible)
{
JniHelper::callStaticVoidMethod(videoHelperClassName, "setVideoVisible", _videoPlayerIndex, visible);
}
void VideoPlayer::addEventListener(const std::string& name, const VideoPlayer::ccVideoPlayerCallback& callback)
{
_eventCallback[name] = callback;
}
void VideoPlayer::onPlayEvent(int event)
{
if (event == QUIT_FULLSCREEN)
{
_fullScreenEnabled = false;
}
else
{
VideoPlayer::EventType videoEvent = (VideoPlayer::EventType)event;
switch (videoEvent) {
case EventType::PLAYING:
_eventCallback["play"]();
break;
case EventType::PAUSED:
_eventCallback["pause"]();
break;
case EventType::STOPPED:
_eventCallback["stoped"]();
break;
case EventType::COMPLETED:
_eventCallback["ended"]();
break;
case EventType::META_LOADED:
_eventCallback["loadedmetadata"]();
break;
case EventType::CLICKED:
_eventCallback["click"]();
break;
case EventType::READY_TO_PLAY:
_eventCallback["suspend"]();
break;
default:
break;
}
}
}
void executeVideoCallback(int index,int event)
{
auto it = s_allVideoPlayers.find(index);
if (it != s_allVideoPlayers.end())
{
s_allVideoPlayers[index]->onPlayEvent(event);
}
}
float VideoPlayer::currentTime() const
{
return JniHelper::callStaticFloatMethod(videoHelperClassName, "getCurrentTime", _videoPlayerIndex);
}
float VideoPlayer::duration() const
{
return JniHelper::callStaticFloatMethod(videoHelperClassName, "getDuration", _videoPlayerIndex);
}
void VideoPlayer::getFrame() {
jbyteArray arr = JniHelper::callObjectByteArrayMethod(s_jobj, videoHelperClassName, "getFrame", _videoPlayerIndex);
if (arr == nullptr) return;
jsize len = JniHelper::getEnv()->GetArrayLength(arr);
if (len == 0) return;
_texDataSize = len;
if (len > _maxDataLen) {
_maxDataLen = len;
if(_videoPixels != nullptr) free(_videoPixels);
_videoPixels = (unsigned char*)malloc(len * sizeof(unsigned char));
}
JniHelper::getEnv()->GetByteArrayRegion(arr, 0, len, reinterpret_cast<jbyte*>(_videoPixels));
JniHelper::getEnv()->DeleteLocalRef(arr);
}
int VideoPlayer::getFrameChannel() const {
return (int)JniHelper::callObjectFloatMethod(s_jobj, videoHelperClassName, "getFrameChannel", _videoPlayerIndex);
}
int VideoPlayer::getFrameWidth() const {
return (int)JniHelper::callObjectFloatMethod(s_jobj, videoHelperClassName, "getFrameWidth", _videoPlayerIndex);
}
int VideoPlayer::getFrameHeight() const {
return (int)JniHelper::callObjectFloatMethod(s_jobj, videoHelperClassName, "getFrameHeight", _videoPlayerIndex);
}
int VideoPlayer::getVideoTexDataSize() const {
return _texDataSize;
}
void VideoPlayer::pushFrameDataToTexture2D(cocos2d::renderer::Texture* tex) const {
if(tex == nullptr) log("Can't find texture!");
else {
if(_videoPixels != nullptr && getFrameWidth() > 0 && getFrameHeight() > 0) {
renderer::Texture::SubImageOption opt(0, 0, getFrameWidth(), getFrameHeight(), 0, false,
false);
opt.imageData = _videoPixels;
((cocos2d::renderer::Texture2D*)tex)->updateSubImage(opt);
}
}
}
void VideoPlayer::setShowRawFrame(bool show) const {
JniHelper::callObjectVoidMethod(s_jobj, videoHelperClassName, "setShowRawFrame", _videoPlayerIndex, show);
}
void VideoPlayer::update() {
//test
}
#endif

View File

@@ -0,0 +1,631 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
http://www.cocos2d-x.org
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.
****************************************************************************/
#include "VideoPlayer.h"
USING_NS_CC;
// No Available on tvOS
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS && !defined(CC_TARGET_OS_TVOS)
//-------------------------------------------------------------------------------------
#import <AVKit/AVPlayerViewController.h>
#import <CoreMedia/CMTime.h>
#import <CoreVideo/CVPixelBuffer.h>
#include "platform/CCApplication.h"
#include "platform/ios/CCEAGLView-ios.h"
#include "platform/CCFileUtils.h"
#include "renderer/gfx/Texture2D.h"
@interface UIVideoViewWrapperIos : NSObject
typedef NS_ENUM(NSInteger, PlayerbackState) {
PlayerbackStateUnknown = 0,
PlayerbackStatePaused,
PlayerbackStopped,
PlayerbackStatePlaying,
PlayerbackStateCompleted
};
@property (assign, nonatomic) AVPlayerViewController * playerController;
- (void) setFrame:(int) left :(int) top :(int) width :(int) height;
- (void) setURL:(int) videoSource :(std::string&) videoUrl;
- (void) play;
- (void) pause;
- (void) resume;
- (void) stop;
- (BOOL) isPlaying;
- (void) seekTo:(float) sec;
- (float) currentTime;
- (float) duration;
- (void) setVisible:(BOOL) visible;
- (void) setKeepRatioEnabled:(BOOL) enabled;
- (void) setFullScreenEnabled:(BOOL) enabled;
- (void) showPlaybackControls:(BOOL) value;
- (BOOL) isFullScreenEnabled;
- (void) cleanup;
-(id) init:(void*) videoPlayer;
- (unsigned char*) getFrame;
- (bool) copyFinished;
- (int) getFrameWidth;
- (int) getFrameHeight;
- (int) getFrameDataSize;
- (int) getBitCount;
- (void) setShowRaw:(BOOL) show;
- (void) clearBuffers;
-(void) videoFinished:(NSNotification*) notification;
@end
@implementation UIVideoViewWrapperIos
{
int _left;
int _top;
int _width;
int _height;
bool _keepRatioEnabled;
bool _fullscreen;
CGRect _restoreRect;
PlayerbackState _state;
VideoPlayer* _videoPlayer;
int _frameWidth;
int _frameHeight;
int _frameDataSize;
int _frameBitCount;
unsigned char* _videoPixels;
bool _finishCopy;
}
-(id)init:(void*)videoPlayer
{
if (self = [super init]) {
_keepRatioEnabled = FALSE;
_left = _top = _width = _height = 0;
[self initPlayerController];
_videoPlayer = (VideoPlayer*)videoPlayer;
}
return self;
}
-(void)initPlayerController
{
self.playerController = [AVPlayerViewController new];
[self setFrame:_left :_top :_width :_height];
[self showPlaybackControls:TRUE];
[self setKeepRatioEnabled:_keepRatioEnabled];
_state = PlayerbackStateUnknown;
_frameWidth = 0;
_frameHeight = 0;
_frameDataSize = 0;
_frameBitCount = 1;
_videoPixels = nullptr;
_finishCopy = false;
[self setShowRaw:YES];
}
-(void) dealloc
{
if(_videoPixels != nullptr) free(_videoPixels);
_videoPlayer = nullptr;
[self cleanup];
[super dealloc];
}
-(void) setFrame:(int)left :(int)top :(int)width :(int)height
{
if (_left == left && _width == width && _top == top && _height == height)
return;
_left = left;
_width = width;
_top = top;
_height = height;
[self.playerController.view setFrame:CGRectMake(left, top, width, height)];
}
-(unsigned char*) getFrame
{
UInt32 type = kCVPixelFormatType_32BGRA;
AVPlayerItem* item = self.playerController.player.currentItem;
if(item.outputs.count == 0) {
NSDictionary* settings = @{ (id)kCVPixelBufferPixelFormatTypeKey : @(type) };
AVPlayerItemVideoOutput* output = [[AVPlayerItemVideoOutput alloc] initWithPixelBufferAttributes:settings];
[item addOutput:output];
}
AVPlayerItemOutput* output = item.outputs[0];
CMTime time = self.playerController.player.currentTime;
CVPixelBufferRef pixelBuffer = [output copyPixelBufferForItemTime:time itemTimeForDisplay:nil];
_frameBitCount = 4;
_frameHeight = (int)CVPixelBufferGetHeight(pixelBuffer);
_frameWidth = (int)CVPixelBufferGetBytesPerRow(pixelBuffer) / _frameBitCount;
_frameDataSize = (int)CVPixelBufferGetDataSize(pixelBuffer);
if(_videoPixels == nullptr && _frameWidth > 0 && _frameHeight > 0) {
_videoPixels = (unsigned char*)calloc(_frameDataSize, 1);
}
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
void* pixels = CVPixelBufferGetBaseAddress(pixelBuffer);
if(_videoPixels != nullptr && pixels != nullptr) {
memcpy(_videoPixels, pixels, _frameDataSize);
_finishCopy = true;
}
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
return _videoPixels;
}
-(bool) copyFinished
{
return _finishCopy;
}
-(int) getFrameWidth
{
return _frameWidth;
}
-(int) getFrameHeight
{
return _frameHeight;
}
-(int) getFrameDataSize
{
return _frameDataSize;
}
-(int) getBitCount
{
return _frameBitCount;
}
-(void) setShowRaw:(BOOL) show
{
if(show == YES) {
self.playerController.view.alpha = 1;
} else {
self.playerController.view.alpha = 0;
}
}
-(void) setFullScreenEnabled:(BOOL) enabled
{
// AVPlayerViewController doesn't provide API to enable fullscreen. But you can toggle
// fullsreen by the playback controllers.
}
-(BOOL) isFullScreenEnabled
{
return false;
}
-(BOOL) isPlaying
{
return (self.playerController.player && self.playerController.player.rate != 0);
}
-(void) setURL:(int)videoSource :(std::string &)videoUrl
{
[self clearBuffers];
[self cleanup];
[self initPlayerController];
if (videoSource == 1)
self.playerController.player = [[[AVPlayer alloc] initWithURL:[NSURL URLWithString:@(videoUrl.c_str())]] autorelease];
else
self.playerController.player = [[[AVPlayer alloc] initWithURL:[NSURL fileURLWithPath:@(videoUrl.c_str())]] autorelease];
[self registerPlayerEventListener];
}
-(void) seekTo:(float)sec
{
if (self.playerController.player)
[self.playerController.player seekToTime:CMTimeMake(sec * 600, 600) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
}
-(float) currentTime
{
if (self.playerController.player)
return CMTimeGetSeconds([self.playerController.player currentTime]);
return -1;
}
-(float) duration
{
if (self.playerController.player)
return CMTimeGetSeconds(self.playerController.player.currentItem.asset.duration);
return -1;;
}
-(void) setVisible:(BOOL)visible
{
[self.playerController.view setHidden:!visible];
if (!visible)
[self pause];
}
-(void) setKeepRatioEnabled:(BOOL)enabled
{
_keepRatioEnabled = enabled;
if (_keepRatioEnabled)
self.playerController.videoGravity = AVLayerVideoGravityResizeAspectFill;
else
self.playerController.videoGravity = AVLayerVideoGravityResize;
}
-(void) play
{
if (self.playerController.player && ![self isPlaying] ) {
[self.playerController.player play];
_state = PlayerbackStatePlaying;
_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::PLAYING);
}
}
-(void) pause
{
if ( [self isPlaying] ) {
[self.playerController.player pause];
_state = PlayerbackStatePaused;
_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::PAUSED);
}
}
-(void) resume
{
if (self.playerController.player && _state == PlayerbackStatePaused)
[self play];
}
-(void) stop
{
// AVPlayer doesn't have `stop` method, so just pause it, and seek time to 0.
if (self.playerController.player && _state != PlayerbackStopped) {
[self seekTo:0];
[self.playerController.player pause];
_state = PlayerbackStopped;
// stop() will be invoked in dealloc, which is invoked by _videoPlayer's destructor,
// so do't send the message when _videoPlayer is being deleted.
if (_videoPlayer)
_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::STOPPED);
}
}
// Private functions
-(void) clearBuffers
{
if(_videoPixels != nullptr) {
free(_videoPixels);
_videoPixels = nullptr;
}
AVPlayerItem* item = self.playerController.player.currentItem;
if(item.outputs.count > 0) {
AVPlayerItemOutput* output = item.outputs[0];
[item removeOutput:output];
[output dealloc];
}
}
-(void) cleanup
{
[self stop];
[self removePlayerEventListener];
[self.playerController.view removeFromSuperview];
[self.playerController release];
}
-(void) removePlayerEventListener {
if (self.playerController.player)
{
[[NSNotificationCenter defaultCenter] removeObserver:self
name:AVPlayerItemDidPlayToEndTimeNotification
object:self.playerController.player.currentItem];
[self.playerController.player removeObserver:self forKeyPath:@"status"];
}
}
-(void) registerPlayerEventListener
{
if (self.playerController.player)
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(videoFinished:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:self.playerController.player.currentItem];
[self.playerController.player addObserver:self forKeyPath:@"status" options:0 context:nil];
}
}
-(void) showPlaybackControls:(BOOL)value
{
self.playerController.showsPlaybackControls = value;
}
-(void) videoFinished:(NSNotification *)notification
{
if(_videoPlayer != nullptr) {
_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::COMPLETED);
_state = PlayerbackStateCompleted;
// Seek to 0 to make it playable again.
[self seekTo:0];
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
auto player = self.playerController.player;
if (object == player && [keyPath isEqualToString:@"status"]) {
if (player.status == AVPlayerStatusReadyToPlay) {
[self addPlayerControllerSubView];
_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::META_LOADED);
_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::READY_TO_PLAY);
} else if (player.status == AVPlayerStatusFailed) {
// something went wrong. player.error should contain some information
NSLog(@"Failed to load video");
}
}
}
-(void)addPlayerControllerSubView {
auto eaglview = (CCEAGLView*)cocos2d::Application::getInstance()->getView();
[eaglview addSubview:self.playerController.view];
}
@end
//------------------------------------------------------------------------------------------------------------
VideoPlayer::VideoPlayer()
: _videoPlayerIndex(-1)
, _fullScreenEnabled(false)
, _fullScreenDirty(false)
, _keepAspectRatioEnabled(false)
{
_videoView = [[UIVideoViewWrapperIos alloc] init:this];
#if CC_VIDEOPLAYER_DEBUG_DRAW
_debugDrawNode = DrawNode::create();
addChild(_debugDrawNode);
#endif
_videoPixels = nullptr;
_texDataSize = 0;
_maxDataLen = 0;
}
VideoPlayer::~VideoPlayer()
{
if(_videoView)
{
[((UIVideoViewWrapperIos*)_videoView) dealloc];
}
}
void VideoPlayer::setURL(const std::string& videoUrl)
{
if (videoUrl.find("://") == std::string::npos)
{
_videoURL = FileUtils::getInstance()->fullPathForFilename(videoUrl);
_videoSource = VideoPlayer::Source::FILENAME;
}
else
{
_videoURL = videoUrl;
_videoSource = VideoPlayer::Source::URL;
}
[((UIVideoViewWrapperIos*)_videoView) setURL:(int)_videoSource :_videoURL];
}
void VideoPlayer::setFullScreenEnabled(bool enabled)
{
[((UIVideoViewWrapperIos*)_videoView) setFullScreenEnabled:enabled];
}
void VideoPlayer::setKeepAspectRatioEnabled(bool enable)
{
if (_keepAspectRatioEnabled != enable)
{
_keepAspectRatioEnabled = enable;
[((UIVideoViewWrapperIos*)_videoView) setKeepRatioEnabled:enable];
}
}
void VideoPlayer::play()
{
if (! _videoURL.empty() && _isVisible)
{
[((UIVideoViewWrapperIos*)_videoView) play];
}
}
void VideoPlayer::pause()
{
if (! _videoURL.empty())
{
[((UIVideoViewWrapperIos*)_videoView) pause];
}
}
void VideoPlayer::stop()
{
if (! _videoURL.empty())
{
[((UIVideoViewWrapperIos*)_videoView) stop];
}
}
void VideoPlayer::seekTo(float sec)
{
if (! _videoURL.empty())
{
[((UIVideoViewWrapperIos*)_videoView) seekTo:sec];
}
}
float VideoPlayer::currentTime()const
{
return [((UIVideoViewWrapperIos*)_videoView) currentTime];
}
float VideoPlayer::duration()const
{
return [((UIVideoViewWrapperIos*)_videoView) duration];
}
void VideoPlayer::setVisible(bool visible)
{
_isVisible = visible;
if (!visible)
{
[((UIVideoViewWrapperIos*)_videoView) setVisible:NO];
}
else
{
[((UIVideoViewWrapperIos*)_videoView) setVisible:YES];
}
}
void VideoPlayer::addEventListener(const std::string& name, const VideoPlayer::ccVideoPlayerCallback& callback)
{
_eventCallback[name] = callback;
}
void VideoPlayer::onPlayEvent(int event)
{
switch ((EventType)event) {
case EventType::PLAYING:
_eventCallback["play"]();
break;
case EventType::PAUSED:
_eventCallback["pause"]();
break;
case EventType::STOPPED:
_eventCallback["stoped"]();
break;
case EventType::COMPLETED:
_eventCallback["ended"]();
break;
case EventType::META_LOADED:
_eventCallback["loadedmetadata"]();
break;
case EventType::CLICKED:
_eventCallback["click"]();
break;
case EventType::READY_TO_PLAY:
_eventCallback["suspend"]();
break;
default:
break;
}
}
void VideoPlayer::setFrame(float x, float y, float width, float height)
{
auto eaglview = (CCEAGLView*)cocos2d::Application::getInstance()->getView();
auto scaleFactor = [eaglview contentScaleFactor];
[((UIVideoViewWrapperIos*)_videoView) setFrame:x/scaleFactor
:y/scaleFactor
:width/scaleFactor
:height/scaleFactor];
}
void VideoPlayer::getFrame()
{
_videoPixels = [((UIVideoViewWrapperIos*)_videoView) getFrame];
}
int VideoPlayer::getFrameChannel() const
{
int res = VideoPlayer::PX_BGRA;
return res;
}
int VideoPlayer::getFrameWidth() const
{
return [((UIVideoViewWrapperIos*)_videoView) getFrameWidth];
}
int VideoPlayer::getFrameHeight() const
{
return [((UIVideoViewWrapperIos*)_videoView) getFrameHeight];
}
int VideoPlayer::getVideoTexDataSize() const
{
return [((UIVideoViewWrapperIos*)_videoView) getFrameDataSize];
}
void VideoPlayer::update()
{
}
void VideoPlayer::pushFrameDataToTexture2D(cocos2d::renderer::Texture* tex) const
{
if(tex == nullptr) {
printf("Can't find texture!\n");
} else {
bool finshCopy = [((UIVideoViewWrapperIos*)_videoView) copyFinished];
if(_videoPixels != nullptr && getFrameWidth() > 0 && getFrameHeight() > 0 && finshCopy) {
renderer::Texture::SubImageOption opt(0, 0, getFrameWidth(), getFrameHeight(), 0, false, false);
opt.imageData = _videoPixels;
((cocos2d::renderer::Texture2D*)tex)->updateSubImage(opt);
}
}
}
void VideoPlayer::setShowRawFrame(bool show) const
{
if(show)
[((UIVideoViewWrapperIos*)_videoView) setShowRaw: YES];
else
[((UIVideoViewWrapperIos*)_videoView) setShowRaw: NO];
}
#endif

View File

@@ -0,0 +1,211 @@
/****************************************************************************
Copyright (c) 2014-2016 Chukong Technologies Inc.
http://www.cocos2d-x.org
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.
****************************************************************************/
#pragma once
#include "base/ccMacros.h"
#include "base/CCData.h"
#include "base/CCRef.h"
#include <functional>
#include <string>
#include <map>
#include "renderer/gfx/Texture2D.h"
#ifndef OBJC_CLASS
#ifdef __OBJC__
#define OBJC_CLASS(name) @class name
#else
#define OBJC_CLASS(name) class name
#endif
#endif // OBJC_CLASS
NS_CC_BEGIN
/**
* @class VideoPlayer
* @brief Displays a video file.
*
* @note VideoPlayer displays a video file base on system widget.
* It's mean VideoPlayer displays a video file above all graphical elements of cocos2d-x.
* @js NA
*/
class VideoPlayer : public Ref
{
public:
/**
* Videoplayer play event type.
*/
enum class EventType
{
PLAYING = 0,
PAUSED,
STOPPED,
COMPLETED,
META_LOADED,
CLICKED,
READY_TO_PLAY
};
VideoPlayer();
/**
* A callback which will be called after specific VideoPlayer event happens.
*/
typedef std::function<void()> ccVideoPlayerCallback;
/**
* Sets a URL as a video source for VideoPlayer.
*/
virtual void setURL(const std::string &_videoURL);
/**
* Starts playback.
*/
virtual void play();
/**
* Pauses playback.
*/
virtual void pause();
/**
* Stops playback.
*/
virtual void stop();
/**
* Seeks to specified time position.
*
* @param sec The offset in seconds from the start to seek to.
*/
virtual void seekTo(float sec);
/**
* Get the current play time, measure in seconds.
*/
float currentTime() const;
float duration() const;
/**
* Get frame rgba pixel as bytes
*/
void getFrame();
int getFrameChannel() const;
int getFrameWidth() const;
int getFrameHeight() const;
int getVideoTexDataSize() const;
void update();
void pushFrameDataToTexture2D(cocos2d::renderer::Texture* tex) const;
void setShowRawFrame(bool show) const;
/**
* Causes the video player to keep aspect ratio or no when displaying the video.
*
* @param enable Specify true to keep aspect ratio or false to scale the video until
* both dimensions fit the visible bounds of the view exactly.
*/
virtual void setKeepAspectRatioEnabled(bool enable);
/**
* Indicates whether the video player keep aspect ratio when displaying the video.
*/
virtual bool isKeepAspectRatioEnabled() const { return _keepAspectRatioEnabled; }
/**
* Causes the video player to enter or exit full-screen mode.
*
* @param fullscreen Specify true to enter full-screen mode or false to exit full-screen mode.
*/
virtual void setFullScreenEnabled(bool fullscreen);
/**
* Register a callback to be invoked when the video state is updated.
*
* @param callback The callback that will be run.
*/
virtual void addEventListener(const std::string& name, const VideoPlayer::ccVideoPlayerCallback& callback);
/**
* @brief A function which will be called when video is playing.
*
* @param event @see VideoPlayer::EventType.
*/
virtual void onPlayEvent(int event);
/**
* Toggle visibility of VideoPlayer.
*/
virtual void setVisible(bool visible);
/**
* Set the rect of VideoPlayer.
*/
virtual void setFrame(float x, float y, float width, float height);
protected:
virtual ~VideoPlayer();
protected:
enum class Source
{
FILENAME = 0,
URL
};
bool _isVisible;
bool _fullScreenDirty;
bool _fullScreenEnabled;
bool _keepAspectRatioEnabled;
std::string _videoURL;
Source _videoSource;
int _videoPlayerIndex;
std::map<std::string, ccVideoPlayerCallback> _eventCallback;
void *_videoView;
int _texDataSize;
private:
unsigned char* _videoPixels;
int _maxDataLen;
static const int PX_RGBA = 3;
static const int PX_RGB565 = 6;
static const int PX_BGRA = 7;
};
NS_CC_END