设计开发

解决Android NDK编译FFmpeg 4.2.2的x86 cpu版时的问题

老规矩,编译环境:Win10 1903,WSL ubuntu,ndk r20b,FFmpeg 4.2.2,首先分享下编译脚本:

#!/bin/bash
make clean

export NDK=/home/kres/android-ndk-r20b
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64/
API=21

function build_android
{
	echo "Compiling FFmpeg for $CPU"
	./configure \
		--prefix=$PREFIX \
		--enable-neon \
		--enable-hwaccels \
		--enable-gpl \
		--enable-postproc \
		--enable-shared \
		--enable-jni \
		--enable-mediacodec \
		--disable-decoders \
		    --enable-decoder=h264_mediacodec \
		    --enable-decoder=vp9 \
		    --enable-decoder=h264 \
		    --enable-decoder=mpeg4 \
		    --enable-decoder=aac \
		    --enable-decoder=aac_latm \
		    --enable-decoder=mjpeg \
		    --enable-decoder=png \
		    --enable-decoder=mpeg4_mediacodec \
		--disable-encoders \
		    --enable-encoder=vp9_vaapi --enable-encoder=h264_nvenc --enable-encoder=h264_v4l2m2m --enable-encoder=hevc_nvenc \
		--disable-demuxers \
		    --enable-demuxer=rtsp --enable-demuxer=rtp --enable-demuxer=flv --enable-demuxer=h264 \
		--disable-muxers \
		    --enable-muxer=rtsp --enable-muxer=rtp --enable-muxer=flv --enable-muxer=h264 \
		--disable-parsers \
		    --enable-parser=mpeg4video --enable-parser=aac --enable-parser=h264 --enable-parser=vp9 \
		--disable-protocols \
		    --enable-protocol=rtmp --enable-protocol=rtp --enable-protocol=tcp --enable-protocol=udp \
		--disable-bsfs \
		--disable-indevs --enable-indev=v4l2 \
		--disable-outdevs \
		--disable-filters \
		--disable-postproc \
		--disable-static \
		--disable-doc \
		--disable-ffmpeg \
		--disable-ffplay \
		--disable-ffprobe \
		--enable-avdevice \
		--disable-doc \
		--disable-symver \
		--cross-prefix=$CROSS_PREFIX \
		--target-os=android \
		--arch=$ARCH \
		--cpu=$CPU \
		--cc=$CC \
		--cxx=$CXX \
		--enable-cross-compile \
		--sysroot=$SYSROOT \
		--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS" \
		--extra-ldflags="$ADDI_LDFLAGS" \
		$ADDITIONAL_CONFIGURE_FLAG

		make clean
		make -j6
		make install
		echo "The Compilation of FFmpeg for $CPU is completed"

}
	#armv8-a
	ARCH=arm64
	CPU=armv8-a
	CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
	CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
	SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
	CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
	PREFIX=$(pwd)/android/$CPU
	OPTIMIZE_CFLAGS="-march=$CPU"
	build_android

	#armv7-a
	ARCH=arm
	CPU=armv7-a
	CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
	CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
	SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
	CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
	PREFIX=$(pwd)/android/$CPU
	OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
	build_android

	#x86
	ARCH=x86
	CPU=x86
	CC=$TOOLCHAIN/bin/i686-linux-android$API-clang
	CXX=$TOOLCHAIN/bin/i686-linux-android$API-clang++
	SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
	CROSS_PREFIX=$TOOLCHAIN/bin/i686-linux-android-
	PREFIX=$(pwd)/android/$CPU
	OPTIMIZE_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"
	build_android

	#x86_64
	ARCH=x86_64
	CPU=x86-64
	CC=$TOOLCHAIN/bin/x86_64-linux-android$API-clang
	CXX=$TOOLCHAIN/bin/x86_64-linux-android$API-clang++
	SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
	CROSS_PREFIX=$TOOLCHAIN/bin/x86_64-linux-android-
	PREFIX=$(pwd)/android/$CPU
	OPTIMIZE_CFLAGS="-march=$CPU -msse4.2 -mpopcnt -m64 -mtune=intel"
	build_android

Continue reading…

由RapidJSON发现的成员函数与宏冲突问题

在使用RapidJson的时候,发现了一个之前很少注意到的问题:

F:\Projects\test\rapidjson-1.1.0\include\rapidjson\document.h(982,70): error : too few arguments provided to function-like macro invocation
if (a < static_cast(-std::numeric_limits::max())

乍一看好像不是很眼熟的错误提示,没看懂什么意思,惯例搜索引擎查,于是很快发现了这个: https://stackoverflow.com/questions/1394132/macro-and-member-function-conflict ,简单一看就反应过来了,原来是成员函数名(这里是max)和之前不知在哪定义过的同名max冲突了,编译器把本该作为成员函数调用的max当成作了替换,于是就出现了上面的错误。

Continue reading…

关于Vue.js项目build后部署到非站点根路径的问题

最近接触了下Vue.js框架,记录个build发布 production 版的部署位置问题:一般情况下,build出的dist直接放到Web服务器的根路径,如 http://www.xxx.com/ 访问就可以了,但如果想要放到子路径下,如 http://www.xxx.com/vue/ ,这时就会发现有资源加载报错了(通过vue-cli一般参数创建的项目, vue版本2.5.2)!

Continue reading…

CocosCreator TypeScript项目引用第三方库的方法和问题记录

TypeScript对于习惯强类型语言(比如Unity C#)而又要写JavaScript项目(比如CocosCreator Egret)的程序员来说,确实提供了很大方便,而且对于一些由于弱类型语言导致的只能运行时检查的低级错误,使用TS都能很好的避免。

这次要记录的是使用TypeScript作为主开发语言的CocosCreator项目中引用第三方库的方法和问题,实测的是MessagePackprotobufjs和Photon这几个库。

Continue reading…

CocosCreator 2.0的cc.eventManager弃用换新API记录

Cocos Creator升级2.0以后发现原来写的一些代码开始报弃用警告了,今天有空学习下新API并更新下原来的代码,之前写的实现监听touch起动停事件的代码是这样写的:

    // use this for initialization
    onLoad: function () {
        let self = this;

        cc.eventManager.addListener({
            event: cc.EventListener.TOUCH_ONE_BY_ONE,

            onTouchBegan: function (touch, event) {
                // x = touch.getLocation().x
                // y = touch.getLocation().y

                return true;
            },
            onTouchMoved: function (touch, event) {
                // x = touch.getLocation().x
                // y = touch.getLocation().y

                return true;
            },
            onTouchEnded: function (touch, event) {
                const x = touch.getLocation().x;
                const y = touch.getLocation().y;
                const cp = self.dragonPlayer.getPosition();
                NetworkManager.instance.getNetPhoton().sendMyPost(cp.x, cp.y, x, y);
                const dist = cc.v2(x, y).sub(cp).mag();
                self.dragonPlayer.stopAllActions();
                self.dragonPlayer.runAction(cc.moveTo(dist / 80, x, y));
                return true;
            }
        }, self.node);
    },
Continue reading…

关于Javascript中类成员函数中内嵌函数的this闭包问题

之前写CocosLua和CocosJS时经常会遇到类成员函数中调用内嵌函数时的this传递问题,最近发现Javascript中可以通过使用箭头函数简化这个this的闭包问题,先给出测试代码:

class clsTest {
  constructor(var1) {
    this._var1 = var1;
  }

  foo() {
    console.log("1111", this._var1);

    (() => {
      console.log("2222", this._var1);
    })();

    (function() {
      console.log("3333", this);
    })();

    let self = this;
    (function() {
      console.log("4444", self._var1);
    })();
  }
}

let objTest = new clsTest(10);
objTest.foo();

JSFiddle:https://jsfiddle.net/u0yconbg/2/

为了简化示例代码,内嵌函数都写成了自调用的形式,可见333时的内嵌函数调用this是undefined,所以4444时在调用函数前声明了self用于闭包进内嵌函数访问this,(Lua中一般是local this = self),而2222的内嵌函数是通过箭头方式声明的,可见log中成功输出了clsTest类对象的_var1成员变量值,也就是说this被自动传递了,为此特意查了下文档:

An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. These function expressions are best suited for non-method functions, and they cannot be used as constructors.

来自:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

屏蔽Cesium的默认双击追踪选中entity行为

Cesium中,默认会对场景中添加的entity进行双击追踪效果(类似Unity中的选中物体后按F),参考

Remove default double click behavior in Cesiumhttp://webiks.com/remove-default-double-click-behavior-in-cesium/

这篇文章中介绍的方法后,发现所谓的”less intrusive way”并不好用,双击选中后的摄像机移动逻辑还是触发了,于是最终采用了第一种解决方法:

viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

实测在1.48版中可以达到效果,另外伴随这个默认双击追踪实体行为的,还有个默认的选中指示框,这个可以通过在new Cesium.Viewer的时候指定selectionIndicator: false来关闭,如下:

var viewer = new Cesium.Viewer('cesiumContainer', {
        'timeline': false,
        'animation': false,
        'homeButton': false,
        'geocoder': false,
        'fullscreenButton': false,
        'searchButton': false,
        'scene3DOnly': false,
        'terrainShadows': Cesium.ShadowMode.DISABLED,
        'navigationHelpButton': false,
        'selectionIndicator': false,
        'sceneModePicker': false,
        'infoBox': false,
        'baseLayerPicker': false,
        'shadows': false,
});

Python 3.6 32bit在Win下安装pycrypto的方法(VS 2017)

在测试一个python操作AES加密解密的脚本时,发现需要安装一些依赖package,大部分直接pip install就搞定了,结果到pycrypto的时候,却遇到了pip报错安装失败的问题,仔细看了下发现是编译出错,搜索了下找到了这个:https://github.com/dlitz/pycrypto/issues/218,原来是需要VS Build Tools环境的问题,按照最后的提示(指定32位编译环境):

for Python 3.6 32 bit following set of commands worked:

cd “C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build”
vcvarsall.bat x86_amd64
cd \
set CL=-FI”%VCINSTALLDIR%\tools\msvc\14.14.26428\include\stdint.h”
pip install pycrypto

执行后,提示:
Continue reading…

Unity中将Animation Clip嵌入Animator Controller的方法

最近再研究Unity的UI动效果,过程中发现一个小细节:在使用UGUI的Button时,如果设置Transition过渡方式为Animation动画,并通过Auto Generate Animation自动生成Animator Controller及四个按钮状态对应的Animation时,会发现生成的Asset资源是这样

和其他FBX动画等一样,动画Animation Clip是直接嵌入Controller的,而当实现一些如UI弹出动画之类的效果时,也使用Animator,自己手动创建Controller后,却没有可视化的直接在创建内嵌Clip以及State的方法,只能创建State然后关联Clip,或者先创建Clip,再拖入Controller自动生成关联State,最后Asset里会是这样:

看着明显不如Button自动生成的那种要整洁!
Continue reading…

Cocos2d-JS HTML5的cc.audioEngine音乐音效在iOS设备上不响应静音键的问题

之前写过一篇同样关于Cocos2d-JS H5的音频播放相关的文章: DOMException: play() can only be initiated by a user gesture(Cocos2d-JS HTML5),其中提到了移动端上H5的声音播放需要在用户操作后且必须在操作后一定时间内的问题,这次记录的问题也与此问题有关,直接现象为Cocos2d-JS(我用的3.13 lite版,通过js-builder获取:http://www.cocos2d-x.org/filecenter/jsbuilder,本文所描述问题可能仅与此版本相关!)的H5游戏在iOS设备上播放的音乐音效不受静音键影响,无法根据静音键静音!
做过iOS音频相关原生开发的应该知道,iOS通过对AVAudioSession的Category设置来决定应用的音频播放所属的分类,从而决定是否受静音键的影响,比如,静音开关开启的时候,短信音,Push消息提示音之类的会不播放,但优酷视频,虾米音乐之类的应用的音频还是会播放,不受影响,具体参考如下:

会话类型 说明 是否要求输入 是否要求输出 是否遵从静音键
AVAudioSessionCategoryAmbient 混音播放,可以与其他音频应用同时播放
AVAudioSessionCategorySoloAmbient 独占播放
AVAudioSessionCategoryPlayback 后台播放,独占
AVAudioSessionCategoryRecord 录音模式
AVAudioSessionCategoryPlayAndRecord 播放和录音,此时可以录音也可以播放
AVAudioSessionCategoryAudioProcessing 硬件解码音频,此时不能播放和录制
AVAudioSessionCategoryMultiRoute 多种输入输出,例如可以耳机、USB设备同时播放

 

Continue reading…