Mac 下安装 Gedit
如果出现打不开“gedit”,因为它来自身份不明的开发者。的问题:参考
https://jingyan.baidu.com/article/f71d60377960651ab741d140.html
关于open 命令
但是我用这种方式安装之后打开的一次之后,在次打开的话一定要完全退出上次的软件, 所以很不舒服,下面介绍第二种方式安装
我并没有用brew cask install gedit这个命令安装 用brew install gedit这个命令,会安装很多依赖,大约5分钟左右
然后就可以gedit文件了,这个界面比通过softonic这种方式的安装界面漂亮多了
代码块 英文状态下直接按左上角就可以,一定是英文状态 中文状态下shit+option+左上角,
echo $PS1
\h:\W \u\$
PS1='${debian_chroot:+($debian_chroot)}\[\e]2;\w\a\]\[\033[01;35m\]\u\[\033[01;37m\]@\[\033[01;34m\]\h \[\033[00m\]: \[\033[01;33m\]\w \[\e[00m\]\[\e[01;36m\][\t \d] \[\e[01;32m\]No.\#(\!)\n\[\e[01;31m\]\$ \[\033[01;37m\]'
export PS1='${debian_chroot:+($debian_chroot)}\[\e]2;\w\a\]\[\033[01;35m\]\u\[\033[01;35m\]@\[\033[01;35m\]\h \[\033[01;35m\]: \[\e[01;36m\]\w \[\e[00m\]\[\e[01;36m\][\t \d] \[\e[01;32m\]No.\#(\!)\n\[\e[01;31m\]\$ \[\033[01;37m\]'
这样就可以显示时间,和历史命令的是第几条的terminal了,是不是很酷
前言之需要了解的东西
MediaCodec MediaCodec类Android提供的用于访问低层多媒体编/解码器接口,它是Android低层多媒体架构的一部分,通常与MediaExtractor、MediaMuxer、AudioTrack结合使用,能够编解码诸如H.264、H.265、AAC、3gp等常见的音视频格式。广义而言,MediaCodec的工作原理就是处理输入数据以产生输出数据。具体来说,MediaCodec在编解码的过程中使用了一组输入/输出缓存区来同步或异步处理数据:首先,客户端向获取到的编解码器输入缓存区写入要编解码的数据并将其提交给编解码器,待编解码器处理完毕后将其转存到编码器的输出缓存区,同时收回客户端对输入缓存区的所有权;然后,客户端从获取到编解码输出缓存区读取编码好的数据进行处理,待处理完毕后编解码器收回客户端对输出缓存区的所有权。不断重复整个过程,直至编码器停止工作或者异常退出
MediaMuxer 就是对音频和视频的混合. 来生成MP4 或 其它格式的文件
没有数据源,比如是从surface出来的 MediaCodec is typically used like this in asynchronous mode:
MediaCodec codec = MediaCodec.createByCodecName(name);
MediaFormat mOutputFormat; // member variable
codec.setCallback(new MediaCodec.Callback() {
@Override
void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
// fill inputBuffer with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
@Override
void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, …) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is equivalent to mOutputFormat
// outputBuffer is ready to be processed or rendered.
…
codec.releaseOutputBuffer(outputBufferId, …);
}
@Override
void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
mOutputFormat = format; // option B
}
@Override
void onError(…) {
…
}
});
codec.configure(format, …);
mOutputFormat = codec.getOutputFormat(); // option B
codec.start();
// wait for processing to complete
codec.stop();
codec.release();
个人认为在有数据源的情况下用这个, 比如已经有了图片要合成视频之类的 MediaCodec is typically used like this in synchronous mode:
MediaCodec codec = MediaCodec.createByCodecName(name);
codec.configure(format, …);
MediaFormat outputFormat = codec.getOutputFormat(); // option B
codec.start();
for (;;) {
int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
if (inputBufferId >= 0) {
ByteBuffer inputBuffer = codec.getInputBuffer(…);
// fill inputBuffer with valid data
…
codec.queueInputBuffer(inputBufferId, …);
}
int outputBufferId = codec.dequeueOutputBuffer(…);
if (outputBufferId >= 0) {
ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
// bufferFormat is identical to outputFormat
// outputBuffer is ready to be processed or rendered.
…
codec.releaseOutputBuffer(outputBufferId, …);
} else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
// Subsequent data will conform to new format.
// Can ignore if using getOutputFormat(outputBufferId)
outputFormat = codec.getOutputFormat(); // option B
}
}
codec.stop();
codec.release();
问题 请看下图, 从Hal上来的数据第一秒的时候是无效的video的, 结束的时候要求多录一秒钟
正常情况下,如果录像开启的话,Video和Audio是同时传上来的, 然后同时合成, 类似mediarecorder 这样的话就不用管, 视频和音频的同步问题了. 因为基本不会有延迟, 但是假如开始的一秒钟我没有video数据.但是停止的时候是以audio停止的, 这样的话我的视频不就少了 一秒的时间, 并且前面的video数据是垃圾帧数据
那假如我多录一秒, 并且让前面的垃圾帧去掉在合成不就可以了,
if (mFirstVideoFrameTimeUs < 0) {
//136899194595
mFirstVideoFrameTimeUs = info.presentationTimeUs;
//第一帧为0
info.presentationTimeUs = 0;
//第一帧解码, return
queueBuffer()
return
}
//每次来算时间的gap 136899227943 这个数在增大,帧的时间戳肯定是在增大
long timeSinceVideoStart = info.presentationTimeUs - mFirstVideoFrameTimeUs;
//33348 是33毫秒 比如1秒30帧, 1帧就是33毫秒左右
info.presentationTimeUs = timeSinceVideoStart - mVideoOffset;
接着我们就可以拿出来一副这样的数据
0 1 2 3 4
0 33348 66695 100042 133397
每一帧到第一帧的时间
为什么要计算时间, 因为我们记录了开始的时间和结束的时间,然后我们录了多长时间也知道,停止的时候我们不就可以达到多录的目的了.
在Linux 或者 Mac系统中如何快速搜索已经使用过的命令?
在Linux中我们可以用history查询已经使用过的命令
并且还可以用 Ctrl + R 来搜索已经用过的命令
我们用一种更快的方式来搜索, 你忘记了以前输入过的某个命令, 只记得开头的几个字母, 没关系 下面我们看看怎么快速补全
输入以下内容
"\e[A": history-search-backward
"\e[B": history-search-forward
set show-all-if-ambiguous on
set completion-ignore-case on
然后你随便输入几个命令. ls, pwd, cd, …. 这个时候想输入pwd, 只用输入p 然后按键盘上键, 命令自动补充完毕. 大大提升工作效率!!
详解targetsdk
<uses-sdk android:minSdkVersion="integer"
android:targetSdkVersion="integer"
android:maxSdkVersion="integer" />
android:minSdkVersion
一个用于指定应用运行所需最低 API 级别的整数。 如果系统的 API 级别低于该属性中指定的值,Android 系统将阻止用户安装应用。 您应该始终声明该属性.
注意:如果您不声明该属性,系统将假定默认值为“1”,这表示您的应用兼容所有 Android 版本。 如果您的应用并不兼容所有版本(例如,它使用 API 级别 3 中引入的 API),并且您尚未声明正确的 minSdkVersion,则当应用安装在 API 级别小于 3 的系统上时,应用将在运行时尝试访问不可用的 API 时发生崩溃。 因此,请务必在 minSdkVersion 属性中声明合适的 API 级别。
android:targetSdkVersion
一个用于指定应用的目标 API 级别的整数。如果未设置,其默认值与为 minSdkVersion 指定的值相等。 该属性用于通知系统,您已针对目标版本进行测试,并且系统不应启用任何兼容性行为来保持您的应用与目标版本的向前兼容性。 应用仍可在较低版本上运行(最低版本为 minSdkVersion)。
在 Android 随着每个新版本的推出而进化的过程中,一些行为甚至是外观可能会发生变化。不过,如果平台的 API 级别高于您的应用的 targetSdkVersion 所声明的版本,系统就可以通过启用兼容性行为来确保您的应用继续以您所期望的方式工作。 您可以通过将 targetSdkVersion 指定为与应用所运行平台的 API 级别一致来停用此类兼容性行为。 例如,如果将该值设置为“11”或更高,系统便可在您的应用运行在 Android 3.0 或更高版本的平台上时对其应用新的默认主题 (Holo),还可在您的应用运行在更大屏幕上时停用屏幕兼容性模式(因为对 API 级别 11 的支持隐含了对更大屏幕的支持)。
系统可根据您为该属性设置的值启用许多兼容性行为。 Build.VERSION_CODES 参考资料中的相应平台版本对其中的几种行为做了说明。
要让您的应用与各 Android 版本保持同步,您应该增加该属性的值,使其与最新 API 级别一致,然后在相应平台版本上对您的应用进行全面测试。
引入的版本:API 级别 4
android:maxSdkVersion
一个指定作为应用设计运行目标的最高 API 级别的整数。 在 Android 1.5、1.6、2.0 及 2.0.1 中,系统会在安装应用以及系统更新后重新验证应用时检查该属性的值。 在任一情况下,如果应用的 maxSdkVersion 属性低于系统本身使用的 API 级别,系统均不允许安装应用。 在系统更新后重新验证这种情况下,这实际上相当于将您的应用从设备中移除。
为说明该属性在系统更新后对您的应用的影响,请看看下面这个示例:
Google Play 上发布了一个在其清单中声明了 maxSdkVersion=”5” 的应用。 一位设备运行 Android 1.6(API 级别 4)的用户下载并安装了该应用。 几周后,该用户收到了 Android 2.0(API 级别 5)OTA 系统更新。 更新安装后,系统检查该应用的 maxSdkVersion 并顺利完成了对其的重新验证。 应用仍可照常工作。 不过,一段时间后,设备又收到了一个系统更新,这次是更新到 Android 2.0.1(API 级别 6)。 更新完成后,系统无法再重新验证应用,因为此时系统本身的 API 级别 (6) 已超过该应用支持的最高级别 (5)。 系统会使该应用对用户不可见,这实际上相当于将它从设备上删除。
警告:不建议声明该属性。 首先,没有必要设置该属性,将其作为阻止您的应用部署到 Android 平台新发布版本上的一种手段。 从设计上讲,新版本平台完全向后兼容。 只要您的应用只使用标准 API 并遵循部署最佳实践,应该能够在新版本平台上正常工作。 其次,请注意在某些情况下,声明该属性可能导致您的应用在系统更新至更高 API 级别后被从用户设备中移除。 大多数可能安装您的应用的设备都会定期收到 OTA 系统更新,因此您应该在设置该属性前考虑这些更新对您的应用的影响。
下面我举个列子: (以运行时权限为例子) 我有一个Android 6.0 系统的手机. 我写了一个app
<uses-sdk android:minSdkVersion="15"
android:targetSdkVersion="28"
android:maxSdkVersion="28" />
这个时候毫无疑问我运行app的时候需要适配运行时权限的代码, 那巧了, 我不想写运行时权限的代码怎么办 可以, 你只需要把targetSdkVersion 设置小于23就可以了 为什么要设置小于23就可以了?
可以看到里面根据了targetsdk的不同而设置了不一样的主题. 其实targetsdk就是为了设置兼容性的. 来确保你的App在新平台上面是否运行一些新特性.
对应项目会运行手机版本内一切特性。譬如项目targetSdkVersion是24,那么项目里没做6.0权限管理,调用危险权限相机就会闪退(利大于弊)
项目运行效果为targetSdkVersion 版本。譬如项目targetSdkVersion是22,那么项目里没做6.0(23)权限处理,调用危险权限如相机不会出现闪退和提示,照常运行,项目特性运行到22版本。
如果目标设备的API版本正好等于此数值, 他会告诉Android平台:此程序在此版本已经经过充分测,没有问题。不必为此程序开启兼容性检查判断的工作了。 也就是说,如果targetSdkVersion与目标设备的API版本相同时,运行效率可能会高一些。 但是,这个设置仅仅是一个声明、一个通知,不会有太实质的作用 用较低的 minSdkVersion 来覆盖最大的人群,用最新的 SDK 设置 targetSdkVersion和 compile 来获得最好的外观和行为。强烈推荐targetSdkVersion升到最新版本。
1. 标题加粗 : #
2. 引用图片资源: 
3. 列表:
第一种方式: *
第二种方式: 1. 2. 这种方式
4. 表格: 上面---, 下面是---, 像下面这样
---
layout: post
title: Markdown语法
category: 工具
tags: Camera API 区别
---
5.超链接有两种方式
第一种: [菜鸟教程](https://www.runoob.com)
第二种: <https://www.runoob.com>
6.如果换行的话在行末加两个空格
7.> 这是引用
8.字体加粗用 **字体**
菜鸟教程 https://www.runoob.com/markdown/md-tutorial.html
持续更新…