# IjkPlayerView **Repository Path**: ts_ohos/IjkPlayerView ## Basic Information - **Project Name**: IjkPlayerView - **Description**: 支持普通和网络视频播放,支持弹幕展示和输入弹幕,支持横竖屏/全屏切换播放模式,支持屏幕滑动操作功能的视频播放器 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2021-09-03 - **Last Updated**: 2024-12-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # IjkPlayerView ## 项目介绍 本项目是基于开源项目[IjkPlayerView](https://github.com/Rukey7/IjkPlayerView) 进行harmonyos化的移植和开发的。 IjkPlayerView是一个基于ijkplayer的视屏播放库,可以用于播放本地和网络视频。 支持普通和网络视频播放,支持弹幕展示和输入弹幕,支持横竖屏/全屏切换播放模式,支持屏幕滑动操作的功能。 #### 项目名称:IjkPlayerView #### 所属系列:harmonyos的第三方组件适配移植 #### 功能:一个适用于harmonyos的Ijk视频播放器 #### 项目移植状态:部分移植 #### 调用差异:由于缺少部分弹幕库扩展内容支持,因此功能只实现部分 #### 原项目GitHub地址:https://github.com/Rukey7/IjkPlayerView ## 支持功能 * m3u8直播流视频播放 * 视屏横屏竖屏切换/全屏切换 * 弹幕的显示,隐藏,发送功能 * 音量,亮度和进度调解 * 全屏和非全屏不同界面展示 * 不同视频源切换播放 * 播放暂停控制功能,双击暂停功能 * UI跟随当前播放状态变化 ## 安装教程 #### 方案一 开发者在自己的项目中添加依赖 ``` //核心引入 implementation project(':playerview') ``` #### 方案二 项目根目录的build.gradle中的repositories添加: ``` buildscript { repositories { ... mavenCentral() } ... } allprojects { repositories { ... mavenCentral() } } ``` module目录的build.gradle中dependencies添加: ``` implementation 'com.gitee.ts_ohos:playerview:1.0.0' ``` ## 使用说明 #### 代码使用 ##### 1.IjkPlayerActivity,实现常规状态下的视频播放。 ````java //播放器初始化配置 mPlayerView.init() .setTitle("这是个跑马灯TextView,标题要足够长才会跑。-(゜ -゜)つロ 乾杯~") .setSkipTip(1184 * 60 * 1) .enableDanmaku() .setVideoSource(null, VIDEO_URL, VIDEO_HD_URL, null, null) .setMediaQuality(IjkPlayerView.MEDIA_QUALITY_HIGH); mPlayerView.initDamukuView("resources/rawfile/bili.xml"); ```` ````java //实现横竖屏自动旋转时的切换 @Override public void onConfigurationUpdated(Configuration configuration) { //获取当前屏幕对应的高度和宽度 int screenWidth = ScreenUtils.getScreenWidth(this); int screenHeight = ScreenUtils.getScreenHeight(this); super.onConfigurationUpdated(configuration); if (configuration.direction == Configuration.DIRECTION_HORIZONTAL) { mPlayerView.setLayoutConfig(new StackLayout.LayoutConfig(screenWidth, screenHeight)); titleBarLayout.setVisibility(Component.HIDE); } else { mPlayerView.setLayoutConfig(new StackLayout.LayoutConfig(screenWidth, 600)); titleBarLayout.setVisibility(Component.VISIBLE); } mPlayerView.configurationChanged(configuration); } ```` ````java //主页面输入内容时,软键盘的控制 @Override protected boolean onTouchEvent(TouchEvent event) { Component component = getCurrentFocus(); if (_isHideSoftInput(component, (int) event.getPointerPosition(event.getIndex()).getX(), (int) event.getPointerPosition(event.getIndex()).getY())) { _closeSoftInput(); return true; } return super.onTouchEvent(event); } private void _closeSoftInput() { mEditText.clearFocus(); SoftInputUtils.closeSoftInput(IjkPlayerActivity.this); mPlayerView.recoverFromEditVideo(); } private boolean _isHideSoftInput(Component view, int x, int y) { if (view == null || !(view instanceof TextField) || !mIsFocus) { return false; } return x < mEtLayout.getLeft() || x > mEtLayout.getRight() || y < mEtLayout.getTop(); } ```` ##### 1.IjkPlayerView,播放器实现类,用于控制播放器内部操作。 ````java //控制视频进度条进度显示和播放 private EventHandler mHandler = new EventHandler(EventRunner.getMainEventRunner()) { @Override protected void processEvent(InnerEvent event) { super.processEvent(event); LogUtil.error("IjkPlayerView.mHandler", "eventId: " + event.eventId); if (event.eventId == MSG_UPDATE_SEEK) { final int pos = _setProgress(); if (!mIsSeeking && mIsShowBar && mVideoView.isPlaying()) { // 这里会重复发送MSG,已达到实时更新 Seek 的效果 event = InnerEvent.get(MSG_UPDATE_SEEK); sendEvent(event, 1000 - (pos % 1000)); } } else if (event.eventId == MSG_ENABLE_ORIENTATION) { // if (mOrientationListener != null) { // mOrientationListener.enable(); // } } else if (event.eventId == MSG_TRY_RELOAD) { if (mIsNetConnected) { reload(); } event = InnerEvent.get(MSG_TRY_RELOAD); sendEvent(event, 3000); } } }; ```` ````java //手势操作相关代码,包括滑动,单击双击等。 mVideoView.setDraggedListener(Component.DRAG_HORIZONTAL_VERTICAL, new DraggedListener() { @Override public void onDragDown(Component component, DragInfo dragInfo) { LogUtil.error("IjkPlayerView.setDraggedListener", "onDragDown: "); handleTouchEvent.handleEvent(component , dragInfo, HandleTouchEvent.TOUCH_STATUS_DOWN); isDownTouch = true; isRecoverFromDanmaku = recoverFromEditVideo(); LogUtil.error("IjkPlayerView.setDraggedListener" , "isFirstDownTouch: " + isFirstDownTouch); LogUtil.error("IjkPlayerView.setDraggedListener" , "isDoubleDownTouch: " + isDoubleDownTouch); if (System.currentTimeMillis() - mFirstTouch > 500) { mFirstTouch = System.currentTimeMillis(); isFirstDownTouch = true; isDoubleDownTouch = false; } else { mFirstTouch = 0; isFirstDownTouch = false; isDoubleDownTouch = true; } if (isFirstDownTouch || !isScroll) { // 弹幕编辑状态返回则不执行单击操作 if (isRecoverFromDanmaku) { } if (mIsShowQuality) { _toggleMediaQuality(); } else { _toggleControlBar(); } } else if (isDoubleDownTouch) { // 如果未进行播放或从弹幕编辑状态返回则不执行双击操作 if (mIsNeverPlay || isRecoverFromDanmaku) { } if (!mIsForbidTouch) { _refreshHideRunnable(); _togglePlayStatus(); } } } @Override public void onDragStart(Component component, DragInfo dragInfo) { LogUtil.error("IjkPlayerView.setDraggedListener", "onDragStart: "); isScroll = true; } @Override public void onDragUpdate(Component component, DragInfo dragInfo) { LogUtil.error("IjkPlayerView.setDraggedListener", "onDragUpdate: "); handleTouchEvent.handleEvent(component , dragInfo, HandleTouchEvent.TOUCH_STATUS_MOVE); isScroll = true; } @Override public void onDragEnd(Component component, DragInfo dragInfo) { LogUtil.error("IjkPlayerView.setDraggedListener", "onDragEnd: "); handleTouchEvent.handleEvent(component , dragInfo, HandleTouchEvent.TOUCH_STATUS_END); isScroll = false; } @Override public void onDragCancel(Component component, DragInfo dragInfo) { LogUtil.error("IjkPlayerView.setDraggedListener" , "onDragCancel: "); handleTouchEvent.handleEvent(component , dragInfo, HandleTouchEvent.TOUCH_STATUS_END); } }); ```` ## 效果展示 ## License Copyright 2016 Rukey7 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.