精选列表

搜索[初体验],共231篇文章
优秀的个人博客,低调大师

Java10 初体验(实战)

最近 IDEA 发布支持 java10的新版本。 Java10 简介: 详细版本更新特性请查看国外的一篇文章:https://www.azul.com/109-new-features-in-jdk-10/ 我在这里只简单的介绍 最热的一个特性:局部变量的类型推断 简单demo: var list = new ArrayList<String>(); // infers ArrayList<String> var stream = list.stream(); // infers Stream<String> 是不是很像js?但是我们要知道,java依旧是强类型语言,只是jvm帮助我们做了变量类型推断。 好了开始正文,java10需要最新版本的IDEA支持。否则JDK你都加不进去。 所以我们先下载最新版的idea: 最新IDEA下载地址:https://www.jetbrains.com/idea/download/#section=windows 安装好后,启动IDEA。 随便进一个项目,然后打开项目架构 快捷键 ctrl + shift + alt + s 添加SDK 给项目适配JDK10 测试 我们都听说过java10的新特性吧。最热的一个特性是 用var 来声明变量,是的,就像js一样。 那接下来直接进入让java粉迫不及待的场面。 /** * Created by Fant.J. */ public class NewJavaTest { public static void main(String[] args) { var list = new ArrayList<>(); list.add(1); list.add("fantj"); list.add(1.00); list.forEach(System.out::println); } } 控制台输出: 1 fantj 1.0 我在这里故意不给ArrayList 赋泛型,因为它默认就是Object,这样我可以给list赋任意类型的变量,给人感觉很像弱类型语言,但是我们应该清楚是因为jvm帮我们猜测了类型。 最后附上java10的官方更新文档:http://openjdk.java.net/jeps/286

优秀的个人博客,低调大师

Groovy初体验:构建高性能JVM应用

为什么要学Groovy Groovy运行于JVM之上,然而其对动态语言、函数式编程范式以及元编程功能的加持所带来的表现力和简洁性可以说甩了Java几条街。我们可以利用Groovy的所有动态功能构建高性能的JVM应用、将开发效率提高几个数量级! 这就是我们为什么要学它! Groovy环境部署 本文实验所用OS为CentOS7,这里介绍使用sdk工具来安装Groovy的方法。 首先在命令行下执行: curl -s get.sdkman.io | bash 接下来执行: source "$HOME/.sdkman/bin/sdkman-init.sh" 然后我们就可以使用sdk工具来安装Groovy: 一句话搞定! sdk install groovy 完成之后我们来检查Groovy安装状态 groovy -v 一切就绪 Hello World From Groovy [root@localhost ~]# vim Hello.groovy [root@localhost ~]# more Hello.groovy println "Hello World From Groovy !" [root@localhost ~]# groovy Hello Hello World From Groovy ! Groovy语言特性 Groovy是轻量级的Java Groovy的信噪比比Java高:较少的代码获得更多结果 GDK = Groovy JDK:通过向JDK的各种类中添加便捷方法,Groovy扩展了JDK形成了GDK库 return语句可选,分号结尾可选 方法和类默认public 导航操作符可帮助实现对象引用不为空时方法才会被调用 Groovy不强迫捕获自己不关心的异常,没捕获的异常自动传到高层 静态方法内可使用this来引用Class对象,因此可以链式调用! 两大优点:表现力 + 简洁!!! 从Java到Groovy 用Java写一段代码如下: public class Greetingss { public static void main( String[] args ) { for( int i=0; i<3; i++ ) { System.out.println("ho "); } System.out.println("Merry Groovy"); } } 用Groovy重构一遍如下: for(i in 0..2) { print 'ho ' } print 'Merry Groovy' 看看两种语言的信噪比对比,真是给人不可估量的感动! 安全导航操作符 ?. 可以避免代码中的大量null引用的判断 def foo( str ) { str?.reverse() // 仅当str不为null时reverse才会执行 } 这可以帮我们省多少个if啊!!! 异常处理 与Java相比,Groovy的异常处理少了很多繁文缛节 对于那些不想处理或者不适合在代码当前层次处理的异常,Groovy对用户不做任何要求,任何用户未处理的异常会自动传递到高一层,我们啥也不用写: def openfile( fileName ) { // 无需throws new FileInputStream( fileName ) // 无需try...catch... 处理 } 异常可以放到其调用代码中处理: try { openFile("nonexistfile") } catch( FileNotFoundException ex ) { print "Oops: " + ex } 若捕获所有异常(Exception),则上面catch中异常的类型都可省略: try { openFile("nonexistfile") } catch( ex ) { // 省略类型表示可捕获所有异常 print "Oops: " + ex } 链式调用 静态方法内可使用this来引用Class对象,因此可以链式调用 class Wizard { def static learn( trick, action ) { //... this } } Wizard.learn('xxxx', {...}) .learn('yyyy', {...}) .learn('zzzz', {...}) 后记 作者更多的原创文章在此: https://www.jianshu.com/u/d19536b0189b

优秀的个人博客,低调大师

使用Docker for Windows初体验

这是第二次使用Docker for Windows了。 最近准备研究一下Docker的一些高级特性如Swarm Clusters,需要用到docker-machine,docker-machine目前仅支持Mac 或 Windows,由于没有Mac所以需要在Windows上运行Docker。官方声称Docker for Windows是一个在Windows系统中创建容器化App的完整开发平台。看完这篇文章,或许你会对Docker和Windows有重新的认识,一改之前对Windows的那些“不好感”。 先放几个截图供查阅: 1.docker 引擎信息 2.容器基本操作 3.容器镜像基本操作: Docker for Windows运行环境要求: 1.当前Docker for Windows版本需要64位Windows 10 Pro、Enterprise或Education(1511 November update, Build 10586 or later)系统,后续版本可能会支持更多Windows 10,Windows Server 2016同样被支持 2.必须启用CPU虚拟化和Hyper-V功能,Hyper-V角色可以在Docker for Windows安装过程中自动安装,可能会重启Windows,一旦安装Docker for Windows,将无法再使用VMware虚拟化产品以及其他虚拟化产品,如无法再使用VMware Workstation和Virtualbox等 Docker for Windows一些基本知识: Docker for Windows运行原理远比现有了解的复杂的多得多,只是简单描述一些已经获得的知识: 1.Docker for Windows的组成部分有多个,不仅包含Windows平台上的一些bin程序供用户使用,也包含了一个基于Hyper-V的虚拟机,虚拟机采用Alpine Linux v3.5操作系统 2.docker volume create指令创建出的数据卷存在在虚拟机中,不易与主机进行交互(Hyper-V虚拟机运行期间无法将磁盘中的数据暴露到主机上),因此数据卷这个功能或许会被-v选项所替代 3.Docker for Windows与PowerShell联用,通过PowerShell来操作docker行为,当然cmd也可以 4.Docker for Windows支持两种容器,Linux container和Windows Container,默认是Linux container,依赖于运行在Hyper-V中的虚拟机。Windows Container并不依赖于虚拟机,但也同样依赖于Hyper-V。两种模式的切换会导致重启Windows,而且显而易见的两种模式下的数据并不共享,它们的配置和数据都是独立存在的。令人意外的是Windows container无法运行依赖Linux环境的容器,如nginx等。 Docker for Windows使用小技巧: 与Linux平台上安装的docker环境基本一样,Docker for Windows同样支持一些共有的特性: 1.配置不安全的registry地址和registry镜像(加速)地址 2.支持数据卷和主机存储路径映射(-v选项),数据卷的支持在Docker for Windows中用起来不方便(参考上文的基本知识),推荐使用-v选项 3.在使用-v选项之前,个人建议在磁盘管理中创建一个vhd虚拟磁盘挂载到主机,比如标记成E盘,然后将这个虚拟磁盘共享给Docker for Windows: 需要注意的是,重启后vhd虚拟磁盘将会不再挂载,需要手动"附加vhd"。 借助Docker for Windows做几件有意思的事儿: 1.重新定义app,将运行在Linux上的app,原生的“放到”Windows中,轻松获得心理上的“原生感” 2.操作容器简单化,不再需要打开VMware等虚拟化产品也不需要再使用端口映射,启动Linux再启动容器这样麻烦,只需要双击运行Docker for Windows,即可使用,外部访问轻松配置 3.开始玩转docker-machine和Swarm Clusters等 开始安装吧!因为一点也不难! 参考链接: 开始使用Docker for Windowshttps://docs.docker.com/docker-for-windows/ 安装Docker for Windowshttps://docs.docker.com/docker-for-windows/install/ tag:Docker for Windows --end-- 本文转自 urey_pp 51CTO博客,原文链接:http://blog.51cto.com/dgd2010/1914864,如需转载请自行联系原作者

优秀的个人博客,低调大师

SQL自动化审核初体验

一、缘起 2015.12.5,广州,ACOUG Asia Tour 广州站 第一次参加ACOUG论坛,会上盖老师分享道:“云时代的DBA将自后向前置、DevOps势在必行—最佳实践是SQL审核”,当时心头一股狂热,原来数据库还能这样玩。 后来也在公司试水SQL审核,制定SQL开发规范、培训开发人员、人肉审核、人肉发布,乐此不疲,以为这就是传说中的数据库DevOps最佳实践;试水一段时间后,发现效果甚微,整个SQL审核过程都是人工,效率很低,而且可笑的是,开发人员也有同样的DB操作权限,干啥要听你DBA的呢?当时很天真的认为,只要DBA在SQL方面比开发更专业,人家就会自觉遵守游戏规则。现在回头看,当时站的太高,过于理想,不够踏实。 2017.5.11-13,北京,DTCC-数据库技术大会 第一次参加DTCC,这应该是转型专职DBA以来,收获最大的3天,全场超过一半讲师都讲到DB自动化运维,自此自动化运维在心里埋下一颗种子。 后来也在公司试水自动化运维,尝试用Python开发了几个小工具,切身感受到自动化带来的便利,自动化确实能避免很多低价值、重复繁琐的劳动。同时也一直在思考,能否借助自动化来实现SQL审核呢?也算是机缘巧合吧,偶然在github上发现一个SQL审核的开源项目archer,折腾试用一番后,两年前的那种狂热又冒出来了。 二、平台介绍 archer 基于inception的自动化SQL操作平台,支持工单、审核、认证、邮件、OSC等功能。 github地址:https://github.com/jly8866/archer 如果对archer做一个分解的话,个人觉得可以分为inception和django inception是内在,负责审核 django是外在,负责展示 ps:这种理解,不知道原作者会不会很郁闷,哈哈 inception 一个集审核、执行、备份及生成回滚语句于一身的MySQL自动化运维工具 github地址:https://github.com/mysql-inception/inception Django Django是一个开放源代码的Web应用框架,由Python写成。采用了MT'V的框架模式,即模型M,模板T和视图V。 三、二次开发 在archer的基础上也做了一些简单的二次开发: 屏蔽单点登录 修复邮件发送bug 显示中文全名 为工程师分配指定的数据库实例 接下来,计划在archer集成更多的功能: MSDB 数据归档 数据库备份 性能报告 巡检报告 四、小结 目前,已经将archer部署到生产环境,也为新上线的某x项目成功发布DB脚本,后续准备逐步铺开。 总的来说,个人觉得效果还是ok的,起码在数据库自动化和DevOps走出了一步,对比两年前的人工审核SQL,总结两点感受最深的经验: 一定要借助自动化工具/平台,纯人工效率实在低 一定要找到合适的审核点,让大家都来遵守,对于SQL审核来说,就是要把DB操作权限掌握在DBA手里,不能对外开放,这点一定要掐死了!!!是的,掐死了,要狠!!!哈哈 五、附录: 最后附上几张平台截图: 原文发布时间为:2018-01-29 本文作者:蓝剑锋 本文来自云栖社区合作伙伴“老叶茶馆”,了解相关信息可以关注“老叶茶馆”微信公众号

优秀的个人博客,低调大师

初体验-阿里云短视频 SDK For Android 快速接入

前言 近期的一些创意短视频 App 风靡年轻群体,比较典型的例如抖音、MUSE 等,阿里云也适时地推出了简单易用的短视频 SDK,帮助开发者们以较低的成本快速引入功能完备的创意短视频功能。本文主要介绍如何快速接入阿里云短视频 SDK 的三个版本(基础版、标准版和专业版)。帮助开发者以最快的速度了解接入的基本方式。 本文描述的阿里云短视频 SDK 版本基于 3.4.0,后续升级接口变动请参考 阿里云短视频 SDK 文档。示例工程代码为 Kotlin,Java 接入类似。 正文 由于三个版本接入方式大同小异,本文将着重介绍基础版接入过程,标准版和专业版可以基于基础版方式接入,后续仅说明接入差异的地方。 基础版接入 1. 引入 aar 以及 so 目前 aar 平台版本最低要求 >= 4.3,先从SDK 下载页面下载相应版本的 SDK,解压之后,将 libs 文件夹下的 QuSdk-RC.aar 拷到 Android 工程模块中的 libs 文件夹下,将 jniLibs 文件夹下的 armeabi-v7a 文件夹也整体拷贝到 libs 文件夹下。拷贝完成之后目录的文件如下: 之后按照如下方式修改 Android 项目工程主模块下的 build.gradle 文件: Step1. 修改 jniLibs 的源文件夹; android { sourceSets.main { jniLibs.srcDir "libs" } } Step2. 将 libs 文件夹加入仓库中; repositories { flatDir { dirs 'libs' } } Step3. 增加 aar 所需依赖。 dependencies { implementation(name: 'QuSdk-RC', ext: 'aar') implementation 'com.android.support:appcompat-v7:24.2.1' implementation 'com.android.support:design:24.2.1' implementation 'com.google.code.findbugs:jsr305:3.0.0' implementation 'com.github.bumptech.glide:glide:3.7.0' implementation 'pub.devrel:easypermissions:0.2.1' implementation 'com.squareup.okhttp3:okhttp:3.2.0' implementation 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar' implementation 'com.squareup.okio:okio:1.12.0' implementation 'com.google.code.gson:gson:2.8.0' } 如果此处遭遇 java.lang.NoSuchFieldError 错误,可以参考短视频安卓常见问题解决。 2. 初始化 SDK 请根据具体的项目情况选择合适的 SDK 初始化时机,Demo 工程在 Applicatioin 的 onCreate() 方法中初始化。 package me.bogerchan.alishortvideodemo import android.app.Application import com.aliyun.common.httpfinal.QupaiHttpFinal /** * Created by hb.chen on 2018/1/6. */ class MyApplication : Application() { override fun onCreate() { super.onCreate() System.loadLibrary("QuCore-ThirdParty") System.loadLibrary("QuCore") QupaiHttpFinal.getInstance().initOkHttpFinal() } } 3. 开始书写你的业务逻辑 经过上述过程,实际上已经接入完成,这时候你可以参考文档直接开始使用各种 API 了,附下示例代码。 package me.bogerchan.alishortvideodemo import android.Manifest import android.app.Activity import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import android.support.v4.app.ActivityCompat import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.aliyun.demo.recorder.AliyunVideoRecorder import com.aliyun.struct.common.VideoQuality import com.aliyun.struct.snap.AliyunSnapVideoParam import me.bogerchan.alishortvideodemo.basic.R class MainActivity : AppCompatActivity() { companion object { val REQUEST_CODE_RECORD_VIDEO = 1 val REQUEST_CODE_FOR_PERMISSION = 2 } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) findViewById(R.id.btn_start_record).setOnClickListener { startRecordActivity() } ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO), REQUEST_CODE_FOR_PERMISSION) } private fun startRecordActivity() { val recordParam = AliyunSnapVideoParam.Builder() .setResolutionMode(AliyunSnapVideoParam.RESOLUTION_720P) .setRatioMode(AliyunSnapVideoParam.RATIO_MODE_9_16) .setRecordMode(AliyunSnapVideoParam.RECORD_MODE_AUTO) .setNeedClip(true) .setMaxDuration(10000) .setMinDuration(2000) .setVideQuality(VideoQuality.HD) .setSortMode(AliyunSnapVideoParam.SORT_MODE_MERGE) .build() AliyunVideoRecorder.startRecordForResult(this, REQUEST_CODE_RECORD_VIDEO, recordParam) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) when (requestCode) { REQUEST_CODE_RECORD_VIDEO -> { if (resultCode == Activity.RESULT_OK && data != null) { val type = data.getIntExtra(AliyunVideoRecorder.RESULT_TYPE, 0) if (type == AliyunVideoRecorder.RESULT_TYPE_CROP) { Toast.makeText(this, "类型为裁剪", Toast.LENGTH_SHORT).show() } else if (type == AliyunVideoRecorder.RESULT_TYPE_RECORD) { Toast.makeText(this, "文件路径为 " + data.getStringExtra(AliyunVideoRecorder.OUTPUT_PATH), Toast.LENGTH_SHORT).show() } } else if (resultCode == Activity.RESULT_CANCELED) { Toast.makeText(this, "用户取消录制", Toast.LENGTH_SHORT).show() } } } } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) when (requestCode) { REQUEST_CODE_FOR_PERMISSION -> { grantResults.forEach { if (it == PackageManager.PERMISSION_DENIED) { Toast.makeText(this, "没有权限,不玩了", Toast.LENGTH_SHORT).show() finish() return@forEach } } } } } } 标准版接入 1. 引入 aar 以及 so 标准版相较于基础版,在引入 so 文件时候多了几个文件,同时 aar 文件名有所变动。最终拷贝结果如下:build.gradle 文件修改与基础版接入一样,只是需要将接入 aar 文件名替换成标准版对应的名字。 2. 初始化 SDK 相较于基础版,需要加载的 so 增多了几个,其中部分 so 文件作为可选功能根据实际情况决定是否加载,具体可以参阅阿里云短视频 SDK 文档。接入后的 Application 文件参考: package me.bogerchan.alishortvideodemo import android.app.Application import com.aliyun.common.httpfinal.QupaiHttpFinal /** * Created by hb.chen on 2018/1/6. */ class MyApplication : Application() { override fun onCreate() { super.onCreate() System.loadLibrary("aliresample") System.loadLibrary("live-openh264") System.loadLibrary("QuCore-ThirdParty") System.loadLibrary("QuCore") QupaiHttpFinal.getInstance().initOkHttpFinal() } } 3. 开始书写你的业务逻辑 经过上述过程,实际上已经接入完成,这时候你可以参考文档直接开始使用各种 API 了,附下示例代码。 package me.bogerchan.alishortvideodemo import android.Manifest import android.content.pm.PackageManager import android.opengl.GLSurfaceView import android.os.Bundle import android.support.v4.app.ActivityCompat import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.aliyun.recorder.AliyunRecorderCreator import com.aliyun.struct.recorder.CameraType import com.aliyun.struct.recorder.MediaInfo import me.bogerchan.alishortvideodemo.std.R class MainActivity : AppCompatActivity() { companion object { val REQUEST_CODE_FOR_PERMISSION = 1 } private val mRecorder by lazy { AliyunRecorderCreator.getRecorderInstance(this) } private var mCameraType = CameraType.FRONT override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO), REQUEST_CODE_FOR_PERMISSION) initAliyunRecorder() findViewById(R.id.btn_start_record).setOnClickListener { Toast.makeText(this, "开始录制片段", Toast.LENGTH_SHORT).show() mRecorder.startRecording() } findViewById(R.id.btn_stop_record).setOnClickListener { Toast.makeText(this, "停止录制片段", Toast.LENGTH_SHORT).show() mRecorder.stopRecording() } findViewById(R.id.btn_finish_record).setOnClickListener { Toast.makeText(this, "结束录制", Toast.LENGTH_SHORT).show() mRecorder.finishRecording() } findViewById(R.id.btn_change_camera_type).setOnClickListener { Toast.makeText(this, "切换前后置", Toast.LENGTH_SHORT).show() mRecorder.switchCamera() } } override fun onStart() { super.onStart() mRecorder.startPreview() } override fun onPause() { super.onPause() mRecorder.stopPreview() } override fun onDestroy() { super.onDestroy() AliyunRecorderCreator.destroyRecorderInstance() } private fun initAliyunRecorder() { mRecorder.setDisplayView(findViewById(R.id.glsv_content) as GLSurfaceView) val mediaInfo = MediaInfo() mediaInfo.videoWidth = 800 mediaInfo.videoHeight = 1200 mediaInfo.isHWAutoSize = true mRecorder.setMediaInfo(mediaInfo) mRecorder.setCamera(mCameraType) mRecorder.setOutputPath(externalCacheDir.absolutePath + "/capture.mp4") } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) when (requestCode) { REQUEST_CODE_FOR_PERMISSION -> { grantResults.forEach { if (it == PackageManager.PERMISSION_DENIED) { Toast.makeText(this, "没有权限,不玩了", Toast.LENGTH_SHORT).show() finish() return@forEach } } } } } } 专业版接入 1. 引入 aar 以及 so 专业版相较于基础版,在引入 so 文件时候多了几个文件,同时 aar 文件名有所变动。最终拷贝结果如下: build.gradle 文件修改与基础版接入一样,只是需要将接入 aar 文件名替换成专业版对应的名字。 2. 初始化 SDK 相较于基础版,需要加载的 so 增多了几个,其中部分 so 文件作为可选功能根据实际情况决定是否加载,具体可以参阅阿里云短视频 SDK 文档。接入后的 Application 文件参考: package me.bogerchan.alishortvideodemo import android.app.Application import com.aliyun.common.httpfinal.QupaiHttpFinal /** * Created by hb.chen on 2018/1/6. */ class MyApplication : Application() { override fun onCreate() { super.onCreate() System.loadLibrary("live-openh264") System.loadLibrary("QuCore-ThirdParty") System.loadLibrary("QuCore") System.loadLibrary("FaceAREngine") System.loadLibrary("AliFaceAREngine") QupaiHttpFinal.getInstance().initOkHttpFinal() } } 3. 开始书写你的业务逻辑 经过上述过程,实际上已经接入完成,这时候你可以参考文档直接开始使用各种 API 了,附下示例代码。 package me.bogerchan.alishortvideodemo import android.Manifest import android.content.pm.PackageManager import android.opengl.GLSurfaceView import android.os.Bundle import android.support.v4.app.ActivityCompat import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.aliyun.recorder.AliyunRecorderCreator import com.aliyun.struct.recorder.CameraType import com.aliyun.struct.recorder.MediaInfo import me.bogerchan.alishortvideodemo.pro.R class MainActivity : AppCompatActivity() { companion object { val REQUEST_CODE_FOR_PERMISSION = 1 } private val mRecorder by lazy { AliyunRecorderCreator.getRecorderInstance(this) } private var mCameraType = CameraType.FRONT override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO), REQUEST_CODE_FOR_PERMISSION) initAliyunRecorder() findViewById(R.id.btn_start_record).setOnClickListener { Toast.makeText(this, "开始录制片段", Toast.LENGTH_SHORT).show() mRecorder.startRecording() } findViewById(R.id.btn_stop_record).setOnClickListener { Toast.makeText(this, "停止录制片段", Toast.LENGTH_SHORT).show() mRecorder.stopRecording() } findViewById(R.id.btn_finish_record).setOnClickListener { Toast.makeText(this, "结束录制", Toast.LENGTH_SHORT).show() mRecorder.finishRecording() } findViewById(R.id.btn_change_camera_type).setOnClickListener { Toast.makeText(this, "切换前后置", Toast.LENGTH_SHORT).show() mRecorder.switchCamera() } } override fun onStart() { super.onStart() mRecorder.startPreview() } override fun onPause() { super.onPause() mRecorder.stopPreview() } override fun onDestroy() { super.onDestroy() AliyunRecorderCreator.destroyRecorderInstance() } private fun initAliyunRecorder() { mRecorder.setDisplayView(findViewById(R.id.glsv_content) as GLSurfaceView) val mediaInfo = MediaInfo() mediaInfo.videoWidth = 800 mediaInfo.videoHeight = 1200 mediaInfo.isHWAutoSize = true mRecorder.setMediaInfo(mediaInfo) mRecorder.setCamera(mCameraType) mRecorder.needFaceTrackInternal(true) mRecorder.setOutputPath(externalCacheDir.absolutePath + "/capture.mp4") } override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) when (requestCode) { REQUEST_CODE_FOR_PERMISSION -> { grantResults.forEach { if (it == PackageManager.PERMISSION_DENIED) { Toast.makeText(this, "没有权限,不玩了", Toast.LENGTH_SHORT).show() finish() return@forEach } } } } } } 结语 至此已经介绍完了阿里云短视频 SDK 的接入方法,示例代码展示的仅仅只是阿里云视频 SDK 强大功能的冰山一角,开发者们可以通过相关的 SDK 文档获取更多的接口信息。如果集成过程中遇到问题,在联系客服之前不妨先看下 常见问题解决,说不定你的问题就在里面。

资源下载

更多资源
优质分享Android(本站安卓app)

优质分享Android(本站安卓app)

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS

Oracle Database,又名Oracle RDBMS,或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是目前世界上流行的关系数据库管理系统,系统可移植性好、使用方便、功能强,适用于各类大、中、小、微机环境。它是一种高效率、可靠性好的、适应高吞吐量的数据库方案。

Sublime Text 一个代码编辑器

Sublime Text 一个代码编辑器

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。