Cocos2dx 3.11版本 视频添加跳过按钮

最近比较忙,这里不写原理只写代码,以后再补。

目前跨平台处理,只在Android和ios实现。其他平台暂时未加。

1.frameworks/cocos2d-x/cocos/ui/UIVideoPlayer.h 

添加一个函数

virtual void addSkipButton();

2.在ios和Android实现的地方实现以下上面的方法

2.1 ios

UIVideoPlayer-ios.mm源码贴过来吧。。。忙。。。

addSkipButton 这里基本实现了三种方式,按钮、text、imgview。其实就是三种控件,我也不太熟悉,但是原理应该一样的吧。前两种,有兴趣的话自己研究,这个代码肯定不行,仅供参考

 


#include "ui/UIVideoPlayer.h"// No Available on tvOS
#if CC_TARGET_PLATFORM == CC_PLATFORM_IOS && !defined(CC_TARGET_OS_TVOS)using namespace cocos2d::experimental::ui;
//-------------------------------------------------------------------------------------

#include "platform/ios/CCEAGLView-ios.h"
#import <MediaPlayer/MediaPlayer.h>
#include "base/CCDirector.h"
#include "platform/CCFileUtils.h"@interface UIVideoViewWrapperIos : NSObject@property (strong,nonatomic) MPMoviePlayerController * moviePlayer;- (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;
- (void) seekTo:(float) sec;
- (void) setVisible:(bool) visible;
- (void) setKeepRatioEnabled:(bool) enabled;
- (void) setFullScreenEnabled:(bool) enabled;
- (bool) isFullScreenEnabled;
- (void) addSkipButton;
- (id) init:(void*) videoPlayer;
-(void)handleTap:(UIButton *)sender;
-(void) videoFinished:(NSNotification*) notification;
-(void) playStateChange;@end@implementation UIVideoViewWrapperIos
{int _left;int _top;int _width;int _height;bool _keepRatioEnabled;VideoPlayer* _videoPlayer;
}-(id)init:(void*)videoPlayer
{if (self = [super init]) {self.moviePlayer = nullptr;_videoPlayer = (VideoPlayer*)videoPlayer;_keepRatioEnabled = false;}return self;
}-(void) dealloc
{if (self.moviePlayer != nullptr) {[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer];[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackStateDidChangeNotification object:self.moviePlayer];[[NSNotificationCenter defaultCenter] removeObserver:self name:@"NSNotificationWillEnterForeground" object:self.moviePlayer];[[NSNotificationCenter defaultCenter] removeObserver:self];[self.moviePlayer stop];[self.moviePlayer.view removeFromSuperview];self.moviePlayer = nullptr;_videoPlayer = nullptr;}[super dealloc];
}-(void) addSkipButton{UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];[button addTarget:self action:@selector(handleTap:) forControlEvents:UIControlEventTouchUpInside];[button setTitle:@"" forState:UIControlStateNormal];std::string path1 =  cocos2d::FileUtils::getInstance()->fullPathForFilename("system_btn/sptg_b_001_1.png");std::string path2 =  cocos2d::FileUtils::getInstance()->fullPathForFilename("system_btn/sptg_b_001_2.png");[button setBackgroundImage:[UIImage imageWithContentsOfFile:[[NSString alloc] initWithFormat:@"%s",path1.c_str()]] forState:UIControlStateNormal];[button setBackgroundImage:[UIImage imageWithContentsOfFile:[[NSString alloc] initWithFormat:@"%s",path2.c_str()]] forState:UIControlStateHighlighted];CGRect rx = [ UIScreen mainScreen ].bounds;[button setFrame:CGRectMake(rx.size.width-120, -20, 164.0, 68.0)];CGAffineTransform transform = button.transform;transform = CGAffineTransformScale(transform, rx.size.width/1280.0, rx.size.height/720.0);button.transform = transform;[self.moviePlayer.view addSubview:button];
}-(void) handleTap:(UIButton *)sender
{if(_videoPlayer != nullptr){[(UIButton *)sender removeFromSuperview];_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::COMPLETED);}
}-(void) setFrame:(int)left :(int)top :(int)width :(int)height
{_left = left;_width = width;_top = top;_height = height;if (self.moviePlayer != nullptr) {[self.moviePlayer.view setFrame:CGRectMake(left, top, width, height)];}
}-(void) setFullScreenEnabled:(bool) enabled
{if (self.moviePlayer != nullptr) {[self.moviePlayer setControlStyle:MPMovieControlStyleNone];[self.moviePlayer setFullscreen:enabled animated:(true)];}
}-(bool) isFullScreenEnabled
{if (self.moviePlayer != nullptr) {return [self.moviePlayer isFullscreen];}return false;
}-(void) setURL:(int)videoSource :(std::string &)videoUrl
{if (self.moviePlayer != nullptr) {[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer];[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackStateDidChangeNotification object:self.moviePlayer];[[NSNotificationCenter defaultCenter] removeObserver:self name:@"NSNotificationWillEnterForeground" object:self.moviePlayer];[self.moviePlayer stop];[self.moviePlayer.view removeFromSuperview];self.moviePlayer = nullptr;}if (videoSource == 1) {self.moviePlayer = [[[MPMoviePlayerController alloc] init] autorelease];self.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;[self.moviePlayer setContentURL:[NSURL URLWithString:@(videoUrl.c_str())]];} else {self.moviePlayer = [[[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:@(videoUrl.c_str())]] autorelease];self.moviePlayer.movieSourceType = MPMovieSourceTypeFile;}self.moviePlayer.allowsAirPlay = false;self.moviePlayer.controlStyle = MPMovieControlStyleNone;self.moviePlayer.view.userInteractionEnabled = true;auto clearColor = [UIColor clearColor];self.moviePlayer.backgroundView.backgroundColor = clearColor;self.moviePlayer.view.backgroundColor = clearColor;for (UIView * subView in self.moviePlayer.view.subviews) {subView.backgroundColor = clearColor;}if (_keepRatioEnabled) {self.moviePlayer.scalingMode = MPMovieScalingModeAspectFit;} else {self.moviePlayer.scalingMode = MPMovieScalingModeFill;}auto view = cocos2d::Director::getInstance()->getOpenGLView();auto eaglview = (CCEAGLView *) view->getEAGLView();[eaglview addSubview:self.moviePlayer.view];[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer];[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playStateChange) name:MPMoviePlayerPlaybackStateDidChangeNotification object:self.moviePlayer];[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(videoFinished:) name:@"NSNotificationWillEnterForeground" object:nil];
}-(void) videoFinished:(NSNotification *)notification
{NSString *name = [notification name];if ([name isEqualToString:@"NSNotificationWillEnterForeground"]) {if (_videoPlayer!= nullptr) {[self resume];}return;}if(_videoPlayer != nullptr){if([self.moviePlayer playbackState] != MPMoviePlaybackStateStopped){_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::COMPLETED);}}
}-(void) playStateChange
{MPMoviePlaybackState state = [self.moviePlayer playbackState];switch (state) {case MPMoviePlaybackStatePaused:_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::PAUSED);break;case MPMoviePlaybackStateStopped:_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::STOPPED);break;case MPMoviePlaybackStatePlaying:_videoPlayer->onPlayEvent((int)VideoPlayer::EventType::PLAYING);break;case MPMoviePlaybackStateInterrupted:break;case MPMoviePlaybackStateSeekingBackward:break;case MPMoviePlaybackStateSeekingForward:break;default:break;}
}-(void) seekTo:(float)sec
{if (self.moviePlayer != NULL) {[self.moviePlayer setCurrentPlaybackTime:(sec)];}
}-(void) setVisible:(bool)visible
{if (self.moviePlayer != NULL) {[self.moviePlayer.view setHidden:!visible];}
}-(void) setKeepRatioEnabled:(bool)enabled
{_keepRatioEnabled = enabled;if (self.moviePlayer != NULL) {if (enabled) {self.moviePlayer.scalingMode = MPMovieScalingModeAspectFit;} else {self.moviePlayer.scalingMode = MPMovieScalingModeFill;}}
}-(void) play
{if (self.moviePlayer != NULL) {[self.moviePlayer.view setFrame:CGRectMake(_left, _top, _width, _height)];[self.moviePlayer play];}
}-(void) pause
{if (self.moviePlayer != NULL) {[self.moviePlayer pause];}
}-(void) resume
{if (self.moviePlayer != NULL) {if([self.moviePlayer playbackState] == MPMoviePlaybackStatePaused){[self.moviePlayer play];}}
}-(void) stop
{if (self.moviePlayer != NULL) {[self.moviePlayer stop];}
}@end
//------------------------------------------------------------------------------------------------------------

VideoPlayer::VideoPlayer()
: _videoPlayerIndex(-1)
, _eventCallback(nullptr)
, _fullScreenEnabled(false)
, _fullScreenDirty(false)
, _keepAspectRatioEnabled(false)
, _isPlaying(false)
{_videoView = [[UIVideoViewWrapperIos alloc] init:this];#if CC_VIDEOPLAYER_DEBUG_DRAW_debugDrawNode = DrawNode::create();addChild(_debugDrawNode);
#endif
}VideoPlayer::~VideoPlayer()
{if(_videoView){[((UIVideoViewWrapperIos*)_videoView) dealloc];}
}void VideoPlayer::setFileName(const std::string& fileName)
{_videoURL = FileUtils::getInstance()->fullPathForFilename(fileName);_videoSource = VideoPlayer::Source::FILENAME;[((UIVideoViewWrapperIos*)_videoView) setURL:(int)_videoSource :_videoURL];
}void VideoPlayer::setURL(const std::string& videoUrl)
{_videoURL = videoUrl;_videoSource = VideoPlayer::Source::URL;[((UIVideoViewWrapperIos*)_videoView) setURL:(int)_videoSource :_videoURL];
}void VideoPlayer::draw(Renderer* renderer, const Mat4 &transform, uint32_t flags)
{cocos2d::ui::Widget::draw(renderer,transform,flags);if (flags & FLAGS_TRANSFORM_DIRTY){auto directorInstance = Director::getInstance();auto glView = directorInstance->getOpenGLView();auto frameSize = glView->getFrameSize();auto scaleFactor = [static_cast<CCEAGLView *>(glView->getEAGLView()) contentScaleFactor];auto winSize = directorInstance->getWinSize();auto leftBottom = convertToWorldSpace(Vec2::ZERO);auto rightTop = convertToWorldSpace(Vec2(_contentSize.width,_contentSize.height));auto uiLeft = (frameSize.width / 2 + (leftBottom.x - winSize.width / 2 ) * glView->getScaleX()) / scaleFactor;auto uiTop = (frameSize.height /2 - (rightTop.y - winSize.height / 2) * glView->getScaleY()) / scaleFactor;[((UIVideoViewWrapperIos*)_videoView) setFrame :uiLeft :uiTop:ceil((rightTop.x - leftBottom.x) * glView->getScaleX() / scaleFactor):ceil(( (rightTop.y - leftBottom.y) * glView->getScaleY()/scaleFactor))];}#if CC_VIDEOPLAYER_DEBUG_DRAW_debugDrawNode->clear();auto size = getContentSize();Point vertices[4]={Point::ZERO,Point(size.width, 0),Point(size.width, size.height),Point(0, size.height)};_debugDrawNode->drawPoly(vertices, 4, true, Color4F(1.0, 1.0, 1.0, 1.0));
#endif
}bool VideoPlayer::isFullScreenEnabled()const
{return [((UIVideoViewWrapperIos*)_videoView) isFullScreenEnabled];
}void VideoPlayer::onEnter()
{Widget::onEnter();[((UIVideoViewWrapperIos*)_videoView) setVisible:YES];
}void VideoPlayer::onExit()
{Widget::onExit();[((UIVideoViewWrapperIos*)_videoView) setVisible:NO];
}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()){[((UIVideoViewWrapperIos*)_videoView) play];}
}void VideoPlayer::pause()
{if (! _videoURL.empty()){[((UIVideoViewWrapperIos*)_videoView) pause];}
}void VideoPlayer::resume()
{if (! _videoURL.empty()){[((UIVideoViewWrapperIos*)_videoView) resume];}
}void VideoPlayer::stop()
{if (! _videoURL.empty()){[((UIVideoViewWrapperIos*)_videoView) stop];}
}void VideoPlayer::addSkipButton(){if (! _videoURL.empty()){[((UIVideoViewWrapperIos*)_videoView) addSkipButton];}
}void VideoPlayer::seekTo(float sec)
{if (! _videoURL.empty()){[((UIVideoViewWrapperIos*)_videoView) seekTo:sec];}
}bool VideoPlayer::isPlaying() const
{return _isPlaying;
}void VideoPlayer::setVisible(bool visible)
{cocos2d::ui::Widget::setVisible(visible);if (! _videoURL.empty()){[((UIVideoViewWrapperIos*)_videoView) setVisible:visible];}
}void VideoPlayer::addEventListener(const VideoPlayer::ccVideoPlayerCallback& callback)
{_eventCallback = callback;
}void VideoPlayer::onPlayEvent(int event)
{if (event == (int)VideoPlayer::EventType::PLAYING) {_isPlaying = true;} else {_isPlaying = false;}if (_eventCallback){_eventCallback(this, (VideoPlayer::EventType)event);}
}cocos2d::ui::Widget* VideoPlayer::createCloneInstance()
{return VideoPlayer::create();
}void VideoPlayer::copySpecialProperties(Widget *widget)
{VideoPlayer* videoPlayer = dynamic_cast<VideoPlayer*>(widget);if (videoPlayer){_isPlaying = videoPlayer->_isPlaying;_fullScreenEnabled = videoPlayer->_fullScreenEnabled;_fullScreenDirty = videoPlayer->_fullScreenDirty;_videoURL = videoPlayer->_videoURL;_keepAspectRatioEnabled = videoPlayer->_keepAspectRatioEnabled;_videoSource = videoPlayer->_videoSource;_videoPlayerIndex = videoPlayer->_videoPlayerIndex;_eventCallback = videoPlayer->_eventCallback;_videoView = videoPlayer->_videoView;}
}#endif

 

2.2Android

c++代码

Android比较恶心,坑比较多,会者不难,难着不会,不好意思,我正好不会。。。

UIVideoPlayer-android.cpp

添加一个函数。这个原理知道吧。。。不知道的模仿其他函数把,就是c++调用java代码。。

void VideoPlayer::addSkipButton()
{if (! _videoURL.empty()){JniHelper::callStaticVoidMethod(videoHelperClassName, "addSkipButton", _videoPlayerIndex);}
}

 

Java代码

两个java文件在 .cocos/platform/android/java/src/org/cocos2dx/lib

这个版本的cocos播放器用的MediaPlayer

1.Cocos2dxVideoHelper.java

/****************************************************************************
Copyright (c) 2014 Chukong Technologies Inc.http://www.cocos2d-x.orgPermission 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.****************************************************************************/package org.cocos2dx.lib;import android.graphics.Rect;
import android.os.Handler;
import android.os.Message;
import android.util.SparseArray;
import android.view.View;
import android.widget.FrameLayout;import android.view.View.OnClickListener;
//import android.widget.Button;import android.util.DisplayMetrics;//todo用按钮的话,这两个删除
import android.widget.ImageView;//todo用按钮的话,这两个删除
import android.graphics.Matrix;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.io.IOException;import org.cocos2dx.lib.Cocos2dxVideoView.OnVideoEventListener;import java.lang.ref.WeakReference;public class Cocos2dxVideoHelper {private FrameLayout mLayout = null;private Cocos2dxActivity mActivity = null;  private SparseArray<Cocos2dxVideoView> sVideoViews = null;static VideoHandler mVideoHandler = null;//private Button skipBtn = null;private ImageView skipImgBtn = null;private int btnIndex = 0;Cocos2dxVideoHelper(Cocos2dxActivity activity,FrameLayout layout){mActivity = activity;mLayout = layout;mVideoHandler = new VideoHandler(this);sVideoViews = new SparseArray<Cocos2dxVideoView>();}private static int videoTag = 0;private final static int VideoTaskCreate = 0;private final static int VideoTaskRemove = 1;private final static int VideoTaskSetSource = 2;private final static int VideoTaskSetRect = 3;private final static int VideoTaskStart = 4;private final static int VideoTaskPause = 5;private final static int VideoTaskResume = 6;private final static int VideoTaskStop = 7;private final static int VideoTaskSeek = 8;private final static int VideoTaskSetVisible = 9;private final static int VideoTaskRestart = 10;private final static int VideoTaskKeepRatio = 11;private final static int VideoTaskFullScreen = 12;private final static int VideoAddSkipBtn = 13;final static int KeyEventBack = 1000;static class VideoHandler extends Handler{WeakReference<Cocos2dxVideoHelper> mReference;VideoHandler(Cocos2dxVideoHelper helper){mReference = new WeakReference<Cocos2dxVideoHelper>(helper);}@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case VideoTaskCreate: {Cocos2dxVideoHelper helper = mReference.get();helper._createVideoView(msg.arg1);break;}case VideoTaskRemove: {Cocos2dxVideoHelper helper = mReference.get();helper._removeVideoView(msg.arg1);break;}case VideoTaskSetSource: {Cocos2dxVideoHelper helper = mReference.get();helper._setVideoURL(msg.arg1, msg.arg2, (String)msg.obj);break;}case VideoTaskStart: {Cocos2dxVideoHelper helper = mReference.get();helper._startVideo(msg.arg1);break;}case VideoTaskSetRect: {Cocos2dxVideoHelper helper = mReference.get();Rect rect = (Rect)msg.obj;helper._setVideoRect(msg.arg1, rect.left, rect.top, rect.right, rect.bottom);break;}case VideoTaskFullScreen:{Cocos2dxVideoHelper helper = mReference.get();Rect rect = (Rect)msg.obj;if (msg.arg2 == 1) {helper._setFullScreenEnabled(msg.arg1, true, rect.right, rect.bottom);} else {helper._setFullScreenEnabled(msg.arg1, false, rect.right, rect.bottom);}break;}case VideoTaskPause: {Cocos2dxVideoHelper helper = mReference.get();helper._pauseVideo(msg.arg1);break;}case VideoTaskResume: {Cocos2dxVideoHelper helper = mReference.get();helper._resumeVideo(msg.arg1);break;}case VideoTaskStop: {Cocos2dxVideoHelper helper = mReference.get();helper._stopVideo(msg.arg1);break;}case VideoTaskSeek: {Cocos2dxVideoHelper helper = mReference.get();helper._seekVideoTo(msg.arg1, msg.arg2);break;}case VideoTaskSetVisible: {Cocos2dxVideoHelper helper = mReference.get();if (msg.arg2 == 1) {helper._setVideoVisible(msg.arg1, true);} else {helper._setVideoVisible(msg.arg1, false);}break;}case VideoTaskRestart: {Cocos2dxVideoHelper helper = mReference.get();helper._restartVideo(msg.arg1);break;}case VideoTaskKeepRatio: {Cocos2dxVideoHelper helper = mReference.get();if (msg.arg2 == 1) {helper._setVideoKeepRatio(msg.arg1, true);} else {helper._setVideoKeepRatio(msg.arg1, false);}break;}case KeyEventBack: {Cocos2dxVideoHelper helper = mReference.get();helper.onBackKeyEvent();break;}case VideoAddSkipBtn: {Cocos2dxVideoHelper helper = mReference.get();helper._addSkipButton(msg.arg1);break;}default:break;}super.handleMessage(msg);}}private class VideoEventRunnable implements Runnable{private int mVideoTag;private int mVideoEvent;public VideoEventRunnable(int tag,int event) {mVideoTag = tag;mVideoEvent = event;}@Overridepublic void run() {nativeExecuteVideoCallback(mVideoTag, mVideoEvent);}}public static native void nativeExecuteVideoCallback(int index,int event);OnVideoEventListener videoEventListener = new OnVideoEventListener() {@Overridepublic void onVideoEvent(int tag,int event) {mActivity.runOnGLThread(new VideoEventRunnable(tag, event));}};public static int createVideoWidget() {Message msg = new Message();msg.what = VideoTaskCreate;msg.arg1 = videoTag;mVideoHandler.sendMessage(msg);return videoTag++;}private void _createVideoView(int index) {Cocos2dxVideoView videoView = new Cocos2dxVideoView(mActivity,index);sVideoViews.put(index, videoView);FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT);mLayout.addView(videoView, lParams);videoView.setZOrderOnTop(true);videoView.setZOrderMediaOverlay(true);videoView.setOnCompletionListener(videoEventListener);}public static void removeVideoWidget(int index){Message msg = new Message();msg.what = VideoTaskRemove;msg.arg1 = index;mVideoHandler.sendMessage(msg);}private void _removeVideoView(int index) {Cocos2dxVideoView view = sVideoViews.get(index);if (view != null) {view.stopPlayback();sVideoViews.remove(index);mLayout.removeView(view);}}public static void setVideoUrl(int index, int videoSource, String videoUrl) {Message msg = new Message();msg.what = VideoTaskSetSource;msg.arg1 = index;msg.arg2 = videoSource;msg.obj = videoUrl;mVideoHandler.sendMessage(msg);}private void _setVideoURL(int index, int videoSource, String videoUrl) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {switch (videoSource) {case 0:videoView.setVideoFileName(videoUrl);break;case 1:videoView.setVideoURL(videoUrl);break;default:break;}}}public static void setVideoRect(int index, int left, int top, int maxWidth, int maxHeight) {Message msg = new Message();msg.what = VideoTaskSetRect;msg.arg1 = index;msg.obj = new Rect(left, top, maxWidth, maxHeight);mVideoHandler.sendMessage(msg);}private void _setVideoRect(int index, int left, int top, int maxWidth, int maxHeight) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {videoView.setVideoRect(left,top,maxWidth,maxHeight);}}public static void setFullScreenEnabled(int index, boolean enabled, int width, int height) {Message msg = new Message();msg.what = VideoTaskFullScreen;msg.arg1 = index;if (enabled) {msg.arg2 = 1;} else {msg.arg2 = 0;}msg.obj = new Rect(0, 0, width, height);mVideoHandler.sendMessage(msg);}private void _setFullScreenEnabled(int index, boolean enabled, int width,int height) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {videoView.setFullScreenEnabled(enabled, width, height);}}private void onBackKeyEvent() {int viewCount = sVideoViews.size();for (int i = 0; i < viewCount; i++) {int key = sVideoViews.keyAt(i);Cocos2dxVideoView videoView = sVideoViews.get(key);if (videoView != null) {videoView.setFullScreenEnabled(false, 0, 0);mActivity.runOnGLThread(new VideoEventRunnable(key, KeyEventBack));}}}public static void startVideo(int index) {Message msg = new Message();msg.what = VideoTaskStart;msg.arg1 = index;mVideoHandler.sendMessage(msg);}private void _startVideo(int index) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {videoView.start();}}public static void pauseVideo(int index) {Message msg = new Message();msg.what = VideoTaskPause;msg.arg1 = index;mVideoHandler.sendMessage(msg);}private void _pauseVideo(int index) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {videoView.pause();}}public static void resumeVideo(int index) {Message msg = new Message();msg.what = VideoTaskResume;msg.arg1 = index;mVideoHandler.sendMessage(msg);}private void _resumeVideo(int index) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {videoView.resume();}}public static void stopVideo(int index) {Message msg = new Message();msg.what = VideoTaskStop;msg.arg1 = index;mVideoHandler.sendMessage(msg);}private void _stopVideo(int index) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {videoView.stop();}//删除跳过按钮
        removeSkipBtn();}public static void restartVideo(int index) {Message msg = new Message();msg.what = VideoTaskRestart;msg.arg1 = index;mVideoHandler.sendMessage(msg);}private void _restartVideo(int index) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {videoView.restart();}}public static void seekVideoTo(int index,int msec) {Message msg = new Message();msg.what = VideoTaskSeek;msg.arg1 = index;msg.arg2 = msec;mVideoHandler.sendMessage(msg);}private void _seekVideoTo(int index,int msec) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {videoView.seekTo(msec);}}public static void setVideoVisible(int index, boolean visible) {Message msg = new Message();msg.what = VideoTaskSetVisible;msg.arg1 = index;if (visible) {msg.arg2 = 1;} else {msg.arg2 = 0;}mVideoHandler.sendMessage(msg);}private void _setVideoVisible(int index, boolean visible) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {if (visible) {videoView.fixSize();videoView.setVisibility(View.VISIBLE);} else {videoView.setVisibility(View.INVISIBLE);}}}public static void setVideoKeepRatioEnabled(int index, boolean enable) {Message msg = new Message();msg.what = VideoTaskKeepRatio;msg.arg1 = index;if (enable) {msg.arg2 = 1;} else {msg.arg2 = 0;}mVideoHandler.sendMessage(msg);}private void _setVideoKeepRatio(int index, boolean enable) {Cocos2dxVideoView videoView = sVideoViews.get(index);if (videoView != null) {videoView.setKeepRatio(enable);}}public static void addSkipButton(int index) {Message msg = new Message();msg.what = VideoAddSkipBtn;msg.arg1 = index;mVideoHandler.sendMessage(msg);}//添加按钮第一种方式 // private void _addSkipButton(int index) {//     skipBtn = new Button(mActivity);//     skipBtn.setText("");//     skipBtn.setX();// x / 1920 *屏幕宽度  y / 1080 *屏幕高度 //     skipBtn.setY(0);//     skipBtn.setWidth(10);//     skipBtn.setHeight(10);//     Cocos2dxVideoView view = sVideoViews.get(index);//     view.skipBtn = skipBtn;//     btnIndex = index;//sptg_b_001_1 这个图片放到 proj.android/res/drawable-xhdpi//     int imgId=mActivity.getResources().getIdentifier("sptg_b_001_1", "drawable", mActivity.getPackageName());//     //skipBtn.setBackgroundDrawable(mActivity.getResources().getDrawable(imgId));//     skipBtn.setBackground(mActivity.getResources().getDrawable(imgId));//     mLayout.addView(skipBtn,0);//     skipBtn.bringToFront();//     skipBtn.invalidate();//     skipBtn.setOnClickListener(new OnClickListener() {//         @Override//         public void onClick(View v) {//             // TODO Auto-generated method stub//             mLayout.removeView(skipBtn);//             skipBtn = null;//             //todo 这个地方处理的不行。要删除视频//             Cocos2dxVideoView view = sVideoViews.get(btnIndex);//             if(view!= null){//                 view.stop();//             }//         }//     });// }//添加按钮第二种方式// private void _addSkipButton(int index) {//     TextView skipButton = new TextView(mActivity);//     skipButton.setText("跳过 >>");//     skipButton.setTextColor(Color.argb(180, 255, 255, 255));//     skipButton.setTextSize(20);//     FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(//     skipButton.getWidth(), skipButton.getHeight());//     params.leftMargin = 20;//     params.topMargin =10;//     skipButton.setLayoutParams(params);//     // Cocos2dxVideoView view = sVideoViews.get(index);//     // view.skipBtn = skipBtn;//    int imgId=mActivity.getResources().getIdentifier("sptg_b_001_1", "drawable", mActivity.getPackageName());//    skipButton.setBackgroundDrawable(mActivity.getResources().getDrawable(imgId));//     mLayout.addView(skipButton,0);//     skipButton.bringToFront();//     skipButton.invalidate();//     skipButton.setOnClickListener(new OnClickListener() {//         @Override//         public void onClick(View v) {//             // TODO Auto-generated method stub//            // mLayout.removeView(skipButton);//             //skipButton = null;//             //stopVideo(index);//         }//     });// }//第三种方式private void _addSkipButton(int index) {skipImgBtn = new ImageView(mActivity);//定义矩阵对象Matrix matrix = new Matrix();//缩放原图matrix.postScale(1.5f, 1.5f);float w = 0;float h = 0;Bitmap bitmap;Bitmap dstbmp;try{bitmap = BitmapFactory.decodeStream(mActivity.getAssets().open("res/system_btn/sptg_b_001_1.png"));dstbmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(), bitmap.getHeight(),matrix,true);skipImgBtn.setImageBitmap(dstbmp);w = dstbmp.getWidth();h = dstbmp.getHeight();}catch(IOException e){//todo
             e.printStackTrace();}//获取屏幕尺寸几种方式// 参考文档 http://blog.csdn.net/ithomer/article/details/6688883DisplayMetrics dm = new DisplayMetrics();mActivity.getWindowManager().getDefaultDisplay().getMetrics(dm);FrameLayout.LayoutParams params = new FrameLayout.LayoutParams((int)w, (int)h);//float density  = dm.density;// int screenWidth  = (int)(dm.widthPixels * density + 0.5f);//  params.leftMargin = (int) (screenWidth-w-20);params.leftMargin = (int) (mActivity.getWindowManager().getDefaultDisplay().getWidth()-w-20);params.topMargin =10;Cocos2dxVideoView view = sVideoViews.get(index);view.skipImgBtn = skipImgBtn;btnIndex = index;skipImgBtn.bringToFront();mLayout.addView(skipImgBtn,params);skipImgBtn.invalidate();skipImgBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {mLayout.removeView(skipImgBtn);skipImgBtn = null;//todo 这个地方处理的不行。要删除视频Cocos2dxVideoView view = sVideoViews.get(btnIndex);if(view!= null){//c处理视频跳过或者完成。因为c++代码里面处理的是COMPLETED 所以直接调用COMPLETED的吧
                    view.mComplete();}}});}public void removeSkipBtn(){if (skipImgBtn!= null){mLayout.removeView(skipImgBtn);skipImgBtn = null;}}
}

其实这样就可以正常显示按钮了。如果不能正常显示的话,需要继续在Cocos2dxVideoView.java 加一个简单的处理。有点乱,以后再整理吧,本次只传源码

 

/** Copyright (C) 2006 The Android Open Source Project* Copyright (c) 2014 Chukong Technologies Inc.** 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 org.cocos2dx.lib;import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;
import android.net.Uri;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.FrameLayout;
import android.widget.MediaController.MediaPlayerControl;//import android.widget.Button;
import android.widget.ImageView;//todo用按钮的话,这两个删除import java.io.IOException;
import java.util.Map;public class Cocos2dxVideoView extends SurfaceView implements MediaPlayerControl {private String TAG = "Cocos2dxVideoView";private Uri         mVideoUri;   private int         mDuration;// all possible internal statesprivate static final int STATE_ERROR              = -1;private static final int STATE_IDLE               = 0;private static final int STATE_PREPARING          = 1;private static final int STATE_PREPARED           = 2;private static final int STATE_PLAYING            = 3;private static final int STATE_PAUSED             = 4;private static final int STATE_PLAYBACK_COMPLETED = 5;/*** mCurrentState is a VideoView object's current state.* mTargetState is the state that a method caller intends to reach.* For instance, regardless the VideoView object's current state,* calling pause() intends to bring the object to a target state* of STATE_PAUSED.*/private int mCurrentState = STATE_IDLE;private int mTargetState  = STATE_IDLE;private boolean isComplete  = false;// All the stuff we need for playing and showing a videoprivate SurfaceHolder mSurfaceHolder = null;private MediaPlayer mMediaPlayer = null;private int         mVideoWidth = 0;private int         mVideoHeight = 0;private OnVideoEventListener mOnVideoEventListener;private MediaPlayer.OnPreparedListener mOnPreparedListener;private int         mCurrentBufferPercentage;private OnErrorListener mOnErrorListener;// recording the seek position while preparingprivate int         mSeekWhenPrepared;  protected Cocos2dxActivity mCocos2dxActivity = null;protected int mViewLeft = 0;protected int mViewTop = 0;protected int mViewWidth = 0;protected int mViewHeight = 0;protected int mVisibleLeft = 0;protected int mVisibleTop = 0;protected int mVisibleWidth = 0;protected int mVisibleHeight = 0;protected boolean mFullScreenEnabled = false;protected int mFullScreenWidth = 0;protected int mFullScreenHeight = 0;private int mViewTag = 0;//  public Button skipBtn = null;public ImageView skipImgBtn = null;public Cocos2dxVideoView(Cocos2dxActivity activity,int tag) {super(activity);mViewTag = tag;mCocos2dxActivity = activity;initVideoView();}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {if (mVideoWidth == 0 || mVideoHeight == 0) {mViewWidth = mVisibleWidth;mViewHeight = mVisibleHeight;setMeasuredDimension(mViewWidth, mViewHeight);Log.i(TAG, ""+mViewWidth+ ":" +mViewHeight);}else {setMeasuredDimension(mVisibleWidth, mVisibleHeight);Log.i(TAG, ""+mVisibleWidth+ ":" +mVisibleHeight);} //328号添加// if (skipBtn != null){//     skipBtn.invalidate();// }//跳过按钮 这个加不加要看在添加视频之前添加还是添加视频之后再添加,这里加不加都行//请求重新draw(),但只会绘制调用者本身。if (skipImgBtn != null){skipImgBtn.invalidate();}}public void setVideoRect(int left, int top, int maxWidth, int maxHeight) {mViewLeft = left;mViewTop = top;mViewWidth = maxWidth;mViewHeight = maxHeight;fixSize(mViewLeft, mViewTop, mViewWidth, mViewHeight);}public void setFullScreenEnabled(boolean enabled, int width, int height) {if (mFullScreenEnabled != enabled) {mFullScreenEnabled = enabled;if (width != 0 && height != 0) {mFullScreenWidth = width;mFullScreenHeight = height;}fixSize();}}public int resolveAdjustedSize(int desiredSize, int measureSpec) {int result = desiredSize;int specMode = MeasureSpec.getMode(measureSpec);int specSize =  MeasureSpec.getSize(measureSpec);switch (specMode) {case MeasureSpec.UNSPECIFIED:/* Parent says we can be as big as we want. Just don't be larger* than max size imposed on ourselves.*/result = desiredSize;break;case MeasureSpec.AT_MOST:/* Parent says we can be as big as we want, up to specSize.* Don't be larger than specSize, and don't be larger than* the max size imposed on ourselves.*/result = Math.min(desiredSize, specSize);break;case MeasureSpec.EXACTLY:// No choice. Do what we are told.result = specSize;break;}return result;}private boolean mNeedResume = false;@Overridepublic void setVisibility(int visibility) {if (visibility == INVISIBLE) {mNeedResume = isPlaying();if (mNeedResume) {mSeekWhenPrepared = getCurrentPosition();}}else if (mNeedResume){start();mNeedResume = false;}super.setVisibility(visibility);}private void initVideoView() {mVideoWidth = 0;mVideoHeight = 0;getHolder().addCallback(mSHCallback);//Fix issue#11516:Can't play video on Android 2.3.x
        getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);setFocusable(true);setFocusableInTouchMode(true);mCurrentState = STATE_IDLE;mTargetState  = STATE_IDLE;}@Overridepublic boolean onTouchEvent(MotionEvent event) {if((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP){if (isPlaying()) {pause();resume();} else if(mCurrentState == STATE_PAUSED){resume();}}return true;}private boolean mIsAssetRouse = false;private String mVideoFilePath = null;private static final String AssetResourceRoot = "assets/";public void setVideoFileName(String path) {if (path.startsWith(AssetResourceRoot)) {path = path.substring(AssetResourceRoot.length());}if (path.startsWith("/")) {mIsAssetRouse = false;setVideoURI(Uri.parse(path),null);}else {mVideoFilePath = path;mIsAssetRouse = true;setVideoURI(Uri.parse(path),null);}}public void setVideoURL(String url) {mIsAssetRouse = false;setVideoURI(Uri.parse(url), null);}/*** @hide*/private void setVideoURI(Uri uri, Map<String, String> headers) {mVideoUri = uri;mSeekWhenPrepared = 0;mVideoWidth = 0;mVideoHeight = 0;openVideo();requestLayout();invalidate();}public void stopPlayback() {if (mMediaPlayer != null) {mMediaPlayer.stop();mMediaPlayer.release();mMediaPlayer = null;mCurrentState = STATE_IDLE;mTargetState  = STATE_IDLE;}}private void openVideo() {if (mSurfaceHolder == null) {// not ready for playback just yet, will try again laterreturn;}if (mIsAssetRouse) {if(mVideoFilePath == null)return;} else if(mVideoUri == null) {return;}// Tell the music playback service to pause// TODO: these constants need to be published somewhere in the framework.Intent i = new Intent("com.android.music.musicservicecommand");i.putExtra("command", "pause");mCocos2dxActivity.sendBroadcast(i);// we shouldn't clear the target state, because somebody might have// called start() previouslyrelease(false);try {//if (mMediaPlayer == null) {mMediaPlayer = new MediaPlayer();mMediaPlayer.setOnPreparedListener(mPreparedListener);mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener);                mMediaPlayer.setOnCompletionListener(mCompletionListener);mMediaPlayer.setOnErrorListener(mErrorListener);mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);mMediaPlayer.setDisplay(mSurfaceHolder);mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mMediaPlayer.setScreenOnWhilePlaying(true);//}
            mDuration = -1;mCurrentBufferPercentage = 0;if (mIsAssetRouse) {AssetFileDescriptor afd = mCocos2dxActivity.getAssets().openFd(mVideoFilePath);mMediaPlayer.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());} else {mMediaPlayer.setDataSource(mCocos2dxActivity, mVideoUri);}mMediaPlayer.prepareAsync();/*** Don't set the target state here either, but preserve the target state that was there before.*/mCurrentState = STATE_PREPARING;} catch (IOException ex) {Log.w(TAG, "Unable to open content: " + mVideoUri, ex);mCurrentState = STATE_ERROR;mTargetState = STATE_ERROR;mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);return;} catch (IllegalArgumentException ex) {Log.w(TAG, "Unable to open content: " + mVideoUri, ex);mCurrentState = STATE_ERROR;mTargetState = STATE_ERROR;mErrorListener.onError(mMediaPlayer, MediaPlayer.MEDIA_ERROR_UNKNOWN, 0);return;}}private boolean mKeepRatio = false;public void setKeepRatio(boolean enabled) {mKeepRatio = enabled;fixSize();}public void fixSize() {if (mFullScreenEnabled) {fixSize(0, 0, mFullScreenWidth, mFullScreenHeight);} else {fixSize(mViewLeft, mViewTop, mViewWidth, mViewHeight);}}public void fixSize(int left, int top, int width, int height) {if (mVideoWidth == 0 || mVideoHeight == 0) {mVisibleLeft = left;mVisibleTop = top;mVisibleWidth = width;mVisibleHeight = height;}else if (width != 0 && height != 0) {if (mKeepRatio) {if ( mVideoWidth * height  > width * mVideoHeight ) {mVisibleWidth = width;mVisibleHeight = width * mVideoHeight / mVideoWidth;} else if ( mVideoWidth * height  < width * mVideoHeight ) {mVisibleWidth = height * mVideoWidth / mVideoHeight;mVisibleHeight = height;}mVisibleLeft = left + (width - mVisibleWidth) / 2;mVisibleTop = top + (height - mVisibleHeight) / 2;} else {mVisibleLeft = left;mVisibleTop = top;mVisibleWidth = width;mVisibleHeight = height;}}else {mVisibleLeft = left;mVisibleTop = top;mVisibleWidth = mVideoWidth;mVisibleHeight = mVideoHeight;}getHolder().setFixedSize(mVisibleWidth, mVisibleHeight);FrameLayout.LayoutParams lParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,FrameLayout.LayoutParams.WRAP_CONTENT);lParams.leftMargin = mVisibleLeft;lParams.topMargin = mVisibleTop;lParams.gravity = Gravity.TOP | Gravity.LEFT;setLayoutParams(lParams);}protected MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =new MediaPlayer.OnVideoSizeChangedListener() {public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {mVideoWidth = mp.getVideoWidth();mVideoHeight = mp.getVideoHeight();if (mVideoWidth != 0 && mVideoHeight != 0) {getHolder().setFixedSize(mVideoWidth, mVideoHeight);}}};MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {public void onPrepared(MediaPlayer mp) {mCurrentState = STATE_PREPARED;if (mOnPreparedListener != null) {mOnPreparedListener.onPrepared(mMediaPlayer);}mVideoWidth = mp.getVideoWidth();mVideoHeight = mp.getVideoHeight();// mSeekWhenPrepared may be changed after seekTo() callint seekToPosition = mSeekWhenPrepared;  if (seekToPosition != 0) {seekTo(seekToPosition);}if (mVideoWidth != 0 && mVideoHeight != 0) {fixSize();} if (mTargetState == STATE_PLAYING) {start();}}};private MediaPlayer.OnCompletionListener mCompletionListener =new MediaPlayer.OnCompletionListener() {public void onCompletion(MediaPlayer mp) {mCurrentState = STATE_PLAYBACK_COMPLETED;mTargetState = STATE_PLAYBACK_COMPLETED;release(true);if (mOnVideoEventListener != null) {mOnVideoEventListener.onVideoEvent(mViewTag,EVENT_COMPLETED);}}};private static final int EVENT_PLAYING = 0;private static final int EVENT_PAUSED = 1;private static final int EVENT_STOPPED = 2;private static final int EVENT_COMPLETED = 3;public interface OnVideoEventListener{void onVideoEvent(int tag,int event);}private MediaPlayer.OnErrorListener mErrorListener =new MediaPlayer.OnErrorListener() {public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {Log.d(TAG, "Error: " + framework_err + "," + impl_err);mCurrentState = STATE_ERROR;mTargetState = STATE_ERROR;/* If an error handler has been supplied, use it and finish. */if (mOnErrorListener != null) {if (mOnErrorListener.onError(mMediaPlayer, framework_err, impl_err)) {return true;}}/* Otherwise, pop up an error dialog so the user knows that* something bad has happened. Only try and pop up the dialog* if we're attached to a window. When we're going away and no* longer have a window, don't bother showing the user an error.*/if (getWindowToken() != null) {Resources r = mCocos2dxActivity.getResources();int messageId;if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {// messageId = com.android.internal.R.string.VideoView_error_text_invalid_progressive_playback;messageId = r.getIdentifier("VideoView_error_text_invalid_progressive_playback", "string", "android");} else {// messageId = com.android.internal.R.string.VideoView_error_text_unknown;messageId = r.getIdentifier("VideoView_error_text_unknown", "string", "android");}int titleId = r.getIdentifier("VideoView_error_title", "string", "android");int buttonStringId = r.getIdentifier("VideoView_error_button", "string", "android");new AlertDialog.Builder(mCocos2dxActivity).setTitle(r.getString(titleId)).setMessage(messageId).setPositiveButton(r.getString(buttonStringId),new DialogInterface.OnClickListener() {public void onClick(DialogInterface dialog, int whichButton) {/* If we get here, there is no onError listener, so* at least inform them that the video is over.*/if (mOnVideoEventListener != null) {mOnVideoEventListener.onVideoEvent(mViewTag,EVENT_COMPLETED);}}}).setCancelable(false).show();}return true;}};private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener =new MediaPlayer.OnBufferingUpdateListener() {public void onBufferingUpdate(MediaPlayer mp, int percent) {mCurrentBufferPercentage = percent;}};/*** Register a callback to be invoked when the media file* is loaded and ready to go.** @param l The callback that will be run*/public void setOnPreparedListener(MediaPlayer.OnPreparedListener l){mOnPreparedListener = l;}/*** Register a callback to be invoked when the end of a media file* has been reached during play back.** @param l The callback that will be run*/public void setOnCompletionListener(OnVideoEventListener l){mOnVideoEventListener = l;}/*** Register a callback to be invoked when an error occurs* during play back or setup.  If no listener is specified,* or if the listener returned false, VideoView will inform* the user of any errors.** @param l The callback that will be run*/public void setOnErrorListener(OnErrorListener l){mOnErrorListener = l;}SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback(){public void surfaceChanged(SurfaceHolder holder, int format,int w, int h){boolean isValidState =  (mTargetState == STATE_PLAYING)|| !isComplete;boolean hasValidSize = (mVideoWidth == w && mVideoHeight == h);if (mMediaPlayer != null && isValidState && hasValidSize) {if (mSeekWhenPrepared != 0) {seekTo(mSeekWhenPrepared);}start();}}public void surfaceCreated(SurfaceHolder holder){mSurfaceHolder = holder;openVideo();}public void surfaceDestroyed(SurfaceHolder holder){// after we return from this we can't use the surface any moremSurfaceHolder = null;if(mCurrentState == STATE_PLAYING) { isComplete = mMediaPlayer.getCurrentPosition() == mMediaPlayer.getDuration(); mSeekWhenPrepared = mMediaPlayer.getCurrentPosition(); }release(true);}};/** release the media player in any state*/private void release(boolean cleartargetstate) {if (mMediaPlayer != null) {mMediaPlayer.reset();mMediaPlayer.release();mMediaPlayer = null;mCurrentState = STATE_IDLE;if (cleartargetstate) {mTargetState  = STATE_IDLE;}}}public void start() {if (isInPlaybackState()) {mMediaPlayer.start();mCurrentState = STATE_PLAYING;if (mOnVideoEventListener != null) {mOnVideoEventListener.onVideoEvent(mViewTag, EVENT_PLAYING);}}mTargetState = STATE_PLAYING;}public void pause() {if (isInPlaybackState()) {if (mMediaPlayer.isPlaying()) {mMediaPlayer.pause();mCurrentState = STATE_PAUSED;if (mOnVideoEventListener != null) {mOnVideoEventListener.onVideoEvent(mViewTag, EVENT_PAUSED);}}}mTargetState = STATE_PAUSED;}public void stop() {if (isInPlaybackState()) {if (mMediaPlayer.isPlaying()) {stopPlayback();if (mOnVideoEventListener != null) {mOnVideoEventListener.onVideoEvent(mViewTag, EVENT_STOPPED);}}}}public void suspend() {release(false);}public void resume() {if (isInPlaybackState()) {if (mCurrentState == STATE_PAUSED) {mMediaPlayer.start();mCurrentState = STATE_PLAYING;if (mOnVideoEventListener != null) {mOnVideoEventListener.onVideoEvent(mViewTag, EVENT_PLAYING);}}}}//新添加完成函数public void mComplete() {if (isInPlaybackState()) {if (mMediaPlayer.isPlaying()) {// mMediaPlayer.stop();mCurrentState = EVENT_COMPLETED;if (mOnVideoEventListener != null) {mOnVideoEventListener.onVideoEvent(mViewTag, EVENT_COMPLETED);}}}mTargetState = EVENT_COMPLETED;}public void restart() {if (isInPlaybackState()) {mMediaPlayer.seekTo(0);mMediaPlayer.start();mCurrentState = STATE_PLAYING;mTargetState = STATE_PLAYING;}}// cache duration as mDuration for faster accesspublic int getDuration() {if (isInPlaybackState()) {if (mDuration > 0) {return mDuration;}mDuration = mMediaPlayer.getDuration();return mDuration;}mDuration = -1;return mDuration;}public int getCurrentPosition() {if (isInPlaybackState()) {return mMediaPlayer.getCurrentPosition();}return 0;}public void seekTo(int msec) {if (isInPlaybackState()) {mMediaPlayer.seekTo(msec);mSeekWhenPrepared = 0;} else {mSeekWhenPrepared = msec;}}public boolean isPlaying() {return isInPlaybackState() && mMediaPlayer.isPlaying();}public int getBufferPercentage() {if (mMediaPlayer != null) {return mCurrentBufferPercentage;}return 0;}public boolean isInPlaybackState() {return (mMediaPlayer != null &&mCurrentState != STATE_ERROR &&mCurrentState != STATE_IDLE &&mCurrentState != STATE_PREPARING);}@Overridepublic boolean canPause() {return true;}@Overridepublic boolean canSeekBackward() {return true;}@Overridepublic boolean canSeekForward() {return true;}public int getAudioSessionId () {return mMediaPlayer.getAudioSessionId();}
}

 

 后续bug:跳过按钮的资源不能使用加密图片,会导致闪退,额额额。

 

忙去了,代码先这样,有问题联系我。QQ776274781 ,各位大神一起交流,哈哈,busy.

转载于:https://www.cnblogs.com/zhangfeitao/p/6647243.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/429458.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

有效数据外含有额外数据_Excel|应用数据有效性规范数据录入

【问题】EXCEL输入数据时&#xff0c;经常会输入不规范或者无效的数据&#xff0c;对数据的统计工作带来很大的麻烦。数据验证能够建立特定的规则&#xff0c;限制单元格可以输入的内容&#xff0c;从而规范数据输入&#xff0c;提高数据统计与分析效率。数据验证&#xff0c;在…

怎么实现hover_web前端CSS实现一个粒子动效的按钮

按钮(button)可能是网页中最常见的组件之一了&#xff0c;大部分都平淡无奇&#xff0c;如果你碰到的是一个这样的按钮&#xff0c;会不会忍不住多点几次呢&#xff1f;通常这类效果第一反应可能就是借助canvas了&#xff0c;比如下面这个案例点击预览(建议去codepen原链接点击…

BZOJ 2242: [SDOI2011]计算器 [快速幂 BSGS]

2242: [SDOI2011]计算器 题意&#xff1a;求\(a^b \mod p,\ ax \equiv b \mod p,\ a^x \equiv b \mod p\)&#xff0c;p是质数 这种裸题我竟然WA了好多次 第三个注意判断a和b整除p的情况 #pragma GCC optimize ("O2") #include <iostream> #include <cstdio…

获取某一列_Excel VBA 8.2 获取多列唯一值,不用肉眼,VBA帮你快速搞定

前景提要(文末提供源码下载)昨天我们学习了针对单列的数据进行获取唯一值的方法&#xff0c;今天我们提升下难度&#xff0c;来尝试下获取已多列为参照物&#xff0c;获取唯一值的方法&#xff0c;昨天有很多小伙伴说还可以用字典的方法更加的简单&#xff0c;其实&#xff0c;…

python求众数代码_python-LeetCode-求众数

题目&#xff1a;给定一个大小为 n 的数组&#xff0c;找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。你可以假设数组是非空的&#xff0c;并且给定的数组总是存在众数。示例 1:输入: [3,2,3]输出: 3示例 2:输入: [2,2,1,1,1,2,2]输出: 2众数——众数(Mode)…

dataoutputstream.write 有时无法发送_RTK实操——CORS官方网教您如何解决RTK无法固定的问题...

测量员在日常测量工作中&#xff0c;非常期盼都能“固定解”&#xff0c;特别是是在密林、高楼下接收信号-测定位置-收工绘图&#xff0c;一整套流程跑完&#xff0c;就稳妥了。然而事与愿违&#xff0c;在使用过程中&#xff0c;有时候会遇到各种各样的复杂状况&#xff0c;导…

《DSP using MATLAB》示例Example7.25

今天清明放假的第二天&#xff0c;早晨出去吃饭时天气有些阴&#xff0c;十点多开始“清明时节雨纷纷”了。 母亲远在他乡看孙子&#xff0c;挺劳累的。父亲照顾生病的爷爷…… 我打算今天把《DSP using MATLAB》第7章结束&#xff0c;剩下的几个例子看不懂了&#xff0c;先跳过…

freemarker使用说明_SpringBoot+Swagger2集成详细说明

SpringBootSwagger2集成详细说明引言&#xff1a;为什么使用Swagger&#xff1f;在Vue没有出来之前&#xff0c;都是前后端在一起&#xff1a;后端用的SSM或者SSH框架前端完全就是静态页面模板引擎。例如&#xff1a;JSP开发久的人应该听说过&#xff0c;和现在的Thymeleaf、 V…

64位 iee754_什么是最大的非规格化和标准化数字?(64bit,IEE 754

我正在使用浮点算法&#xff0c;因为我很想理解这个主题&#xff01;我知道这些数字可以用科学记数法表示。因此&#xff0c;对于这两个数字&#xff0c;指数应该如下所示&#xff1a;非规范化数&#xff1a; 11 .... 11所以(1 1/2 1/2 ^ 2 ... 1/2 ^ 52)* 2 ^ 1023归一化数…

Vim中根据正则对选中文本对齐(比如ini文件的=号对齐)

vimrc增加如下内容即可&#xff1a; vnoremap <M-> :call Duiqi(\v(^\s*\S)\s(.*))<CR> "reg匹配的第2段文字对齐 function! Duiqi(reg) let l0 line("<") let l1 line(">") "获取第1个单词及前面空格的最大长度 let…

mysql pid_mysql pid文件是什么用途

展开全部MySQL pid 文件记录的是当前 mysqld 进程的 pid&#xff0c;pid 亦即 Process ID。可以通过如下的例子查62616964757a686964616fe58685e5aeb931333361316634看&#xff1a;$ /etc/init.d/mysqld startStarting MySQL. SUCCESS!$ ll /data/mysql/centos.pid-rw-rw---- 1…

[bzoj1305][CQOI2009]dance跳舞

一次舞会有n个男孩和n个女孩。每首曲子开始时&#xff0c;所有男孩和女孩恰好配成n对跳交谊舞。每个男孩都不会和同一个女孩跳两首或更多舞曲。有一些男孩女孩相互喜欢&#xff0c;而其他相互不喜欢&#xff08;不会“单向喜欢”&#xff09;。每个男孩最多只愿意和k个不喜欢的…

mysql主从架构搭建_mysql主从架构搭建

背景知识&#xff1a;主从这个架构可以实现数据备份&#xff0c;数据在多个服务器上分布等等&#xff0c;当然最主要的优点是可以实现负载均衡&#xff0c;将写操作交给主节点&#xff0c;读操作交给从节点。mysql官网有很多版本&#xff0c;例如Enterprise(企业版需要付费&…

Linux快速搭建FTP服务器

FTP 是File Transfer Protocol&#xff08;文件传输协议&#xff09;的英文简称&#xff0c;而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时&#xff0c;它也是一个应用程序&#xff08;Application&#xff09;。基于不同的操作系统有不同的FTP应用程序…

mysql 连接 监控_mysql监控优化(一)连接数和缓存

一、mysql的连接数MYSQL数据库安装完成后&#xff0c;默认最大连接数是100&#xff0c;一般流量稍微大一点的论坛或网站这个连接数是远远不够的&#xff0c;连接数少的话&#xff0c;在大并发下连接数会不够用&#xff0c;会有很多线程在等待其他连接释放&#xff0c;就可能会导…

集合框架(一) ----------Map集合遍历的方法

import java.util.*; /** * Map集合遍历的方法 * author Administrator * */public class Test2 { public static void main(String[] args) { Map<String,String> mapnew HashMap<String,String>(); /*Java 提供两种不同的类型&#xff1a; * 引用类型和原始类型&…

mysql事务总结_MySQL数据库和相关事务总结

以下的文章主要向大家描述的是MySQL数据库和相关事务&#xff0c;在实际操作中有很多人都认为MySQL数据库对事务处理是不支持的&#xff0c;其实&#xff0c;只要MySQL数据库版本支持BDB或是InnoDB表类型&#xff0c;那么你的MySQL就具有事务处理的能力。这里面&#xff0c;又以…

please reinstall the mysql distribution_php安装扩展mysqli的实现步骤及报错解决办法

php安装扩展mysqli的实现步骤及报错解决办法terminal#cd php-5.3.6/ext/mysqli#/usr/local/webserver/php/bin/phpize#./configure --with-php-config/usr/local/webserver/php/bin/php-config#make#make instal报错&#xff1a;checking for MySQLi support... yeschecking wh…

day35-hibernate映射 03-Hibernate持久态对象自动更新数据库

持久态对象一个非常重要的能力:自动更新数据库。 package cn.itcast.hibernate3.demo1;import static org.junit.Assert.*;import org.hibernate.Session; import org.hibernate.Transaction; import org.junit.Test;import cn.itcast.utils.HibernateUtils;/*** Hibernate的测…

mysql视图中调用函数写法_从视图中调用函数

{"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],"search_count":[{"count_phone":5,"count":5}]},"card":[{"des":"阿里云函数计算(Function Compute)是一个事件…