Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
hexleo committed Sep 3, 2020
0 parents commit 8ed9825
Show file tree
Hide file tree
Showing 304 changed files with 25,849 additions and 0 deletions.
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# dependencies
node_modules
# logs
npm-debug.log

# Nuxt generate
.vscode

.idea

# sw.*

.cache

#mac cache
.DS_Store
12 changes: 12 additions & 0 deletions Android/PlayerProj/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
*.iml
.gradle
/local.properties
/.idea/caches/build_file_checksums.ser
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.idea
.DS_Store
/build
/captures
.externalNativeBuild
1 change: 1 addition & 0 deletions Android/PlayerProj/animplayer/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
36 changes: 36 additions & 0 deletions Android/PlayerProj/animplayer/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

// 内部maven上传
apply from: file("../maven.gradle")

android {
compileSdkVersion 28



defaultConfig {
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

}

dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version") {
exclude module: 'annotations'
}
}

// jcenter 上传(这个要在底部)
// apply from: file("publish.gradle")
21 changes: 21 additions & 0 deletions Android/PlayerProj/animplayer/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
33 changes: 33 additions & 0 deletions Android/PlayerProj/animplayer/publish.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
ext {
// 此处填写刚才建立的maven仓库的仓库名称
bintrayRepo = 'maven'
// library的group id
publishedGroupId = 'com.egame.vap'
// library网站地址
siteUrl = 'https://github.com/Tencent/vap'
// library仓库地址
gitUrl = 'https://github.com/Tencent/vap'

// 注册时候的bintray username
developerId = 'hexleo'
// 开发者名称
developerName = 'hexleo'
// 开发者邮箱
developerEmail = '[email protected]'

// 开源许可证(这里是Apache 2.0)
licenseName = 'MIT'
licenseUrl = 'http://opensource.org/licenses/MIT'
allLicenses = ["MIT"]

// library artifact(单个module一般就填写library name)
artifact = 'animplayer'
libraryName = 'animplayer'
libraryVersion = '2.0.6'
libraryDescription = ''
// bintrayName 是你在网页Repository页面能看到的名称
bintrayName = 'vap'
}

apply from: '../installv1.gradle'
apply from: '../bintrayv1.gradle'
2 changes: 2 additions & 0 deletions Android/PlayerProj/animplayer/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tencent.qgame.animplayer"/>
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Tencent is pleased to support the open source community by making vap available.
*
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the MIT License (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://opensource.org/licenses/MIT
*
* 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.tencent.qgame.animplayer

import android.graphics.Bitmap
import android.graphics.MaskFilter
import com.tencent.qgame.animplayer.mask.MaskConfig
import com.tencent.qgame.animplayer.util.ALog
import org.json.JSONException
import org.json.JSONObject

/**
* vapc里读取出来的基础配置
*/
class AnimConfig {

companion object {
private const val TAG = "${Constant.TAG}.AnimConfig"
}

val version = 2 // 不同版本号不兼容
var totalFrames = 0 // 总帧数
var width = 0 // 需要显示视频的真实宽高
var height = 0
var videoWidth = 0 // 视频实际宽高
var videoHeight = 0
var orien = Constant.ORIEN_DEFAULT // 0-兼容模式 1-竖屏 2-横屏
var fps = 0
var isMix = false // 是否为融合动画
var alphaPointRect = PointRect(0, 0 ,0 ,0) // alpha区域
var rgbPointRect = PointRect(0, 0, 0, 0) // rgb区域
var isDefaultConfig = false // 没有vapc配置时默认逻辑
var defaultVideoMode = Constant.VIDEO_MODE_SPLIT_HORIZONTAL

var maskConfig: MaskConfig ?= null
var jsonConfig: JSONObject? = null


/**
* @return 解析是否成功,失败按默认配置走
*/
fun parse(json: JSONObject): Boolean {
return try {
json.getJSONObject("info").apply {
val v = getInt("v")
if (version != v) {
ALog.e(TAG, "current version=$version target=$v")
return false
}
totalFrames = getInt("f")
width = getInt("w")
height = getInt("h")
videoWidth = getInt("videoW")
videoHeight = getInt("videoH")
orien = getInt("orien")
fps = getInt("fps")
isMix = getInt("isVapx") == 1
val a = getJSONArray("aFrame") ?: return false
alphaPointRect = PointRect(a.getInt(0), a.getInt(1), a.getInt(2), a.getInt(3))
val c = getJSONArray("rgbFrame") ?: return false
rgbPointRect = PointRect(c.getInt(0), c.getInt(1), c.getInt(2), c.getInt(3))
}
true
} catch (e : JSONException) {
ALog.e(TAG, "json parse fail $e", e)
false
}
}

override fun toString(): String {
return "AnimConfig(version=$version, totalFrames=$totalFrames, width=$width, height=$height, videoWidth=$videoWidth, videoHeight=$videoHeight, orien=$orien, fps=$fps, isMix=$isMix, alphaPointRect=$alphaPointRect, rgbPointRect=$rgbPointRect, isDefaultConfig=$isDefaultConfig)"
}


}


data class PointRect(val x: Int, val y: Int, val w: Int, val h: Int)
data class RefVec2(val w: Int, val h: Int) //参考宽&高
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
/*
* Tencent is pleased to support the open source community by making vap available.
*
* Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
*
* Licensed under the MIT License (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
*
* http://opensource.org/licenses/MIT
*
* 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.tencent.qgame.animplayer

import android.os.SystemClock
import com.tencent.qgame.animplayer.util.ALog
import org.json.JSONObject
import java.nio.charset.Charset

/**
* 配置管理
*/
class AnimConfigManager(val player: AnimPlayer) {

companion object {
private const val TAG = "${Constant.TAG}.AnimConfigManager"
}

var config: AnimConfig? = null
var isParsingConfig = false // 是否正在读取配置

/**
* 解析配置
* @return true 解析成功 false 解析失败
*/
fun parseConfig(fileContainer: FileContainer, defaultVideoMode: Int, defaultFps: Int): Int {
try {
isParsingConfig = true
// 解析vapc
val time = SystemClock.elapsedRealtime()
val result = parse(fileContainer, defaultVideoMode, defaultFps)
ALog.i(TAG, "parseConfig cost=${SystemClock.elapsedRealtime() - time}ms")
if (!result) {
isParsingConfig = false
return Constant.REPORT_ERROR_TYPE_PARSE_CONFIG
}
// 插件解析配置
val resultCode = config?.let {
player.pluginManager.onConfigCreate(it)
} ?: Constant.OK
isParsingConfig = false
return resultCode
} catch (e : Throwable) {
ALog.e(TAG, "parseConfig error $e", e)
isParsingConfig = false
return Constant.REPORT_ERROR_TYPE_PARSE_CONFIG
}
}

/**
* 默认配置解析(兼容老视频格式)
*/
fun defaultConfig(_videoWidth: Int, _videoHeight: Int) {
if (config?.isDefaultConfig == false) return
config?.apply {
videoWidth = _videoWidth
videoHeight = _videoHeight
if (defaultVideoMode == Constant.VIDEO_MODE_SPLIT_VERTICAL) { // 上下对齐
width = _videoWidth
height = _videoHeight / 2
alphaPointRect = PointRect(0, 0, width, height)
rgbPointRect = PointRect(0, height, width, height)
} else { // 默认左右对齐
width = _videoWidth / 2
height = _videoHeight
alphaPointRect = PointRect(0, 0, width, height)
rgbPointRect = PointRect(width, 0, width, height)
}
}
}


private fun parse(fileContainer: FileContainer, defaultVideoMode: Int, defaultFps: Int): Boolean {

val config = AnimConfig()
this.config = config


// 查找vapc box
fileContainer.startRandomRead()
val boxHead = ByteArray(8)
var head: BoxHead? = null
var vapcStartIndex: Long = 0
while (fileContainer.read(boxHead, 0, boxHead.size) == 8) {
val h = parseBoxHead(boxHead) ?: break
if ("vapc" == h.type) {
h.startIndex = vapcStartIndex
head = h
break
}
vapcStartIndex += h.length
fileContainer.skip(h.length - 8L)
}

if (head == null) {
ALog.e(TAG, "vapc box head not found")
// 按照默认配置生成config
config.apply {
isDefaultConfig = true
this.defaultVideoMode = defaultVideoMode
fps = defaultFps
}
return true
}

// 读取vapc box
val vapcBuf = ByteArray(head.length - 8) // ps: OOM exception
fileContainer.read(vapcBuf, 0 , vapcBuf.size)
fileContainer.closeRandomRead()

val json = String(vapcBuf, 0, vapcBuf.size, Charset.forName("UTF-8"))
val jsonObj = JSONObject(json)
config.jsonConfig = jsonObj
val result = config.parse(jsonObj)
if (defaultFps > 0) {
config.fps = defaultFps
}
player.fps = config.fps
return result
}

private fun parseBoxHead(boxHead: ByteArray): BoxHead? {
if (boxHead.size != 8) return null
val head = BoxHead()
var length: Int = 0
length = length or (boxHead[0].toInt() and 0xff shl 24)
length = length or (boxHead[1].toInt() and 0xff shl 16)
length = length or (boxHead[2].toInt() and 0xff shl 8)
length = length or (boxHead[3].toInt() and 0xff)
head.length = length
head.type = String(boxHead, 4, 4, Charset.forName("US-ASCII"))
return head
}

private class BoxHead {
var startIndex: Long = 0
var length: Int = 0
var type: String? = null
}



}
Loading

0 comments on commit 8ed9825

Please sign in to comment.