地址:
rtsp://$(IP):$(PORT)/user=$(USER)&password=$(PWD)&channel=$(Channel)&stream=$(Stream).sdp?real_stream
示例:
rtsp://10.6.10.25:554/user=admin&password=&channel=1&stream=0.sdp?real_stream channel 通道 stream 码流 (0主码 1次码)
参考链接:
地址:
rtsp://$(IP):$(PORT)/user=$(USER)&password=$(PWD)&channel=$(Channel)&stream=$(Stream).sdp?real_stream
示例:
rtsp://10.6.10.25:554/user=admin&password=&channel=1&stream=0.sdp?real_stream channel 通道 stream 码流 (0主码 1次码)
参考链接:
多线程同时增加和获取数据的情况:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
new Main().test();
}
private List<String> mData = new ArrayList<>();
private List<String> mCloneData;
private int count = 0;
public void test() {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
mData.add(count++ + "");
mCloneData = null;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
for (String string : getData()) {
System.out.println(string);
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}).start();
}
private List<String> getData() {
if (mCloneData == null) {
mCloneData = new ArrayList<>(mData);
}
return mCloneData;
}
}
import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.widget.VideoView;
import java.io.File;
public class VideoManager {
private VideoView mVideoView;
private MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
@SuppressLint("CheckResult")
public VideoManager(VideoView videoView) {
mVideoView = videoView;
// 设置准备完成监听
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
// 准备完成后开始播放
mp.start();
}
});
// 设置播放信息监听
mVideoView.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
// 视频帧开始渲染时设置背景透明
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
mVideoView.setBackgroundColor(Color.TRANSPARENT);
}
return true;
}
});
}
/**
* 播放视频
*/
public void play(String path) {
// 设置背景
setBackground(path);
// 设置视频地址
mVideoView.setVideoPath(path);
}
/**
* 设置背景
*/
private void setBackground(String path) {
File file = new File(path);
if (file.exists()) {
mediaMetadataRetriever.setDataSource(path);
Bitmap bitmap = mediaMetadataRetriever.getFrameAtTime(1);
mVideoView.setBackground(new BitmapDrawable(null, bitmap));
}
}
}
参考链接:
笔者在新电脑上运行之前做的项目时遇到了闪退问题。这个项目之前运行的一直很好,笔者找了很久才找到问题的原因。
笔者在新电脑上运行项目的时候,是运行在一个x86架构的模拟器上面的。笔者的项目中要生成一个so文件,而且笔者的项目中设置了so过滤,只留下了armeabi-v7a架构。然而Android Studio运行项目时只生成了x86架构的so文件,所以打包以后armeabi-v7a目录下就没有这个so文件。
解决方案也很简单,用Android Studio来Build一下APK就可以了,这样会生成所有支持的架构的so文件,然后再运行就不会报错了。
后记:后来经过反复测试发现Android Studio运行项目时只生成了x86架构的so文件的原因是Gradle版本太低。升级Gradle版本到5.4.1,Gradle插件版本到3.5.0就解决了这个问题。
查看CPU支持的ABIs优先级列表:
cat /system/build.prop | grep ro.product.cpu.abilist=
笔者的x86模拟器:
ro.product.cpu.abilist=x86,armeabi-v7a,armeabi
参考链接:
指定ndk需要兼容的架构
defaultConfig {
ndk {
abiFilters "armeabi-v7a" // 只兼容armeabi-v7a架构
}
}
各种CPU架构支持的ABIs优先级列表。
| ARMv5 | armeabi(1) |
| ARMv7 | armeabi(2)|armeabi-v7a(1) |
| ARMv8 | armeabi(3)|armeabi-v7a(2)|arm64-v8a(1) |
| x86 | armeabi(3)|armeabi-v7a(2)|x86(1) |
| x86_64 | armeabi(4)|armeabi-v7a(3)|x86(2)|x86_64(1) |
| MIPS | mips(1) |
| MIPS64 | mips(2)|mips64(1) |
参考链接:
pre {
font-size: 0.8em;
}
code {
background-color: rgba(0, 0, 0, 0.01);
border: 1px solid rgba(51, 51, 51, 0.1);
padding: 0.2em;
}
注:/wp-content/themes/twentyfifteen/css/editor-style.css 也有改动