2025-03-24 15:41:12
先是去看了黄花风铃。
南宁行道树的一种,特别是东葛路一路上全是。但是在青秀山是直接开了两个山谷,还是比较震撼的。
然后是第一次看到的樱花,之前觉得也就和桃花差不多,实际上不太一样,桃花更“热烈”些。适马30 1.4
裁切出来的,糊完了
然后是莫奈主题
花园
在上传这些文件的时候, 我minio的读写异常地高,不知为何
2024-12-18 11:39:14
工作中用这个库维护了一套Excel、word的导出导入工具。可以说是能力比较强大的库了。比apache的poi要强。氪金就是牛。
https://mirrors.tuna.tsinghua.edu.cn/Adoptium/
最喜欢用的openjdk
Bilibili
目前来讲,国内比较好的视频平台。由于广告、画质、正版受害者等比较影响体验的问题,已经不续费了。
Baidu
用百度没啥问题,主要是省事,记得装个插件把csdn纳入过滤
工作原因,需要实现一些GIS场景,这个算最成熟的框架了,国内很多产品都是基于这个实现的。
网络活菩萨,永远的神
基本就是RSS订阅一些新闻,看的其实不多
E
横空出世的国产Nas系统,跑了个在本地的pve用起来还行,目前还在快速迭代上升期。
目前来讲最好的RSS阅读器,其实现了一个平台,可以用RSS把孤立的博客聚合起来。之前我有想过,能否实现一个聚合平台,定义一个通用协议,或者直接使用Nostr协议,不同的博客可以接入,后来不了了之。
十年之约,把博客接入了。
没思路就上去看看吧,说不定人家做好了。
很快,很好,七牛可以说是相当慷慨了
## HostHatch
vps, 适合做大盘鸡跑pt。
Github项目推荐,已经加到RSS订阅,有时候会有一些有趣的项目
如果你是java开发,可以用一下。
`curl ip.sb` 可以得到你的公网出口ip
## Jetbrains
Idea 依然是Java开发最好的选择,每年都会订阅。同系列的其他应用也很好用。
https://mirrors.tuna.tsinghua.edu.cn/
清华和中科大的源经常使用,特别是Linux发行版镜像和软件源。
和软件源类似,js包仓库
水平很高。Vue3库,博客部分用到了这个。
24年最火AI公司
新兴宝塔竞品,够用,如果你的同事不太会Linux,可以试一下。
用过最好的远程工具,丝滑。目前需要配置代理用于登录账号,隧道打通后不用代理。
雨云,除了硬盘小点,其他还行。
反复入门,目前可以写一些简单的东西了,学习曲线比较陡峭。
https://course.rs/first-try/sth-you-should-not-do.html 跟着这个教程学的
https://rustcc.cn/ 社区,还算活跃的社区
程序员很多,话题比较水深火热
开始一个前端项目,Vue3是个好选择
Notion 国内平替,更低的订阅价格,差不多的功能
2024-11-28 16:26:15
本来mp4文件是直接nginx代理的,但是最近把图片音视频迁移到家里的minio里了,nginx不好直接代理到,索性实现个接口
直接上代码, 看注释得了。
func videoServ(ctx *gin.Context) {
filepath := ctx.Param("filepath")
key := strings.Join([]string{config.CONFIG_INTANCE.DataDir, "videos", filepath}, "/")
// 渠道object
obj, err := storage.ReadFromMC(key)
if err != nil {
ctx.AbortWithError(http.StatusInternalServerError, err)
return
}
// 取到文件大小
fileInfo, err := obj.Stat()
fileSize := fileInfo.Size
// 获取浏览器的请求头
rangeHeader := ctx.GetHeader("Range")
// 空的就按全部大小来写入
if rangeHeader == "" {
// No Range header, send full file
ctx.Header("Content-Length", strconv.FormatInt(fileInfo.Size, 10))
ctx.Header("Accept-Ranges", "bytes")
ctx.Header("Content-Type", "video/mp4")
ctx.DataFromReader(http.StatusOK, fileInfo.Size, "video/mp4", obj, nil)
return
}
// 解析Range头
rangeSpec := strings.TrimPrefix(rangeHeader, "bytes=")
startEnd := strings.SplitN(rangeSpec, "-", 2)
// 获取开始值
start, err := strconv.ParseInt(startEnd[0], 10, 64)
if err != nil || start < 0 {
ctx.JSON(http.StatusRequestedRangeNotSatisfiable, gin.H{"error": "Invalid start byte range"})
return
}
// 获取结束值
var end int64
if len(startEnd) == 2 && startEnd[1] != "" {
end, err = strconv.ParseInt(startEnd[1], 10, 64)
// 超了就按最大
if err != nil || end > fileSize-1 {
end = fileSize - 1
}
} else {
// 没有 也是最大
end = fileSize - 1
}
// 值不对
if start > end || start > fileSize-1 {
ctx.JSON(http.StatusRequestedRangeNotSatisfiable, gin.H{"error": "Requested range not satisfiable"})
return
}
// 设置响应头
contentLength := end - start + 1
// bytes start-end/total
ctx.Header("Content-Range", fmt.Sprintf("bytes %d-%d/%d", start, end, fileSize))
// acccept 头
ctx.Header("Accept-Ranges", "bytes")
ctx.Header("Content-Length", strconv.FormatInt(contentLength, 10))
ctx.Header("Content-Type", "video/mp4")
// 206 code
ctx.Status(http.StatusPartialContent)
// 跳到开始的地方
_, err = obj.Seek(start, io.SeekStart)
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Could not seek to start byte"})
return
}
// 写入lenght长度
io.CopyN(ctx.Writer, obj, contentLength)
obj.Close()
}
2024-09-26 23:53:38
去了个人少的海滩,阳光把沙子晒得烫脚。
大海有个比较好的地方元素比较少,稍微构图就好了。
偶尔也试试正方形构图
适马30mm 1.4 下的人像,非常给力。
2024-09-14 16:19:02
有个机器上的服务可能会炸掉,在修复之前直接重启。懂不懂let it crash.哲学
#!/bin/bash
PORT=端口
SERVICE_NAME=服务名称
if ! nc -z localhost $PORT; then
echo "Port $PORT is not active. Attempting to start $SERVICE_NAME..."
systemctl start $SERVICE_NAME
if systemctl is-active --quiet $SERVICE_NAME; then
echo "$SERVICE_NAME has been started successfully."
else
echo "Failed to start $SERVICE_NAME."
fi
else
echo "Port $PORT is active."
fi
2024-09-13 17:15:47
关键点在于shader的编写
通过按帧号的方式去计算采样的点位
vec4 colorImage = texture(image, vec2(fract(st.s * 50.0 - speed * czm_frameNumber * 50.0 * 0.01), st.t));
被采样的贴图会被绘制到折线上。
import * as Cesium from 'cesium';
/*
流动纹理线
color 颜色
duration 持续时间 毫秒
*/
function PolylineTrailLinkMaterialProperty (color, speed, duration, imageUrl) {
this._definitionChanged = new Cesium.Event()
this._color = undefined
this._colorSubscription = undefined
this.color = color
this.speed = speed
this.duration = duration
this._time = new Date().getTime()
this.imageUrl = imageUrl
}
Object.defineProperties(PolylineTrailLinkMaterialProperty.prototype, {
isConstant: {
get: function () {
return false
}
},
definitionChanged: {
get: function () {
return this._definitionChanged
}
},
color: Cesium.createPropertyDescriptor('color')
})
PolylineTrailLinkMaterialProperty.prototype.getType = function (time) {
return 'PolylineTrailLink'
}
PolylineTrailLinkMaterialProperty.prototype.getValue = function (time, result) {
// debugger
if (!Cesium.defined(result)) {
result = {}
}
result.color = Cesium.Property.getValueOrClonedDefault(
this._color,
time,
Cesium.Color.WHITE,
result.color
)
result.image = this.imageUrl ? this.imageUrl : Cesium.Material.PolylineTrailLinkImage
result.time = ((new Date().getTime() - this._time) % this.duration) / this.duration
result.speed = this.speed
return result
}
PolylineTrailLinkMaterialProperty.prototype.equals = function (other) {
return (
this === other ||
(other instanceof PolylineTrailLinkMaterialProperty &&
Property.equals(this._color, other._color))
)
}
// Cesium.PolylineTrailLinkMaterialProperty = PolylineTrailLinkMaterialProperty
Cesium.Material.PolylineTrailLinkType = 'PolylineTrailLink'
Cesium.Material.PolylineTrailLinkImage = '/fire.png'
Cesium.Material.PolylineTrailLinkSource =
`czm_material czm_getMaterial(czm_materialInput materialInput)
{
czm_material material = czm_getDefaultMaterial(materialInput);
vec2 st = materialInput.st;
vec4 colorImage = texture(image, vec2(fract(st.s * 50.0 - speed * czm_frameNumber * 50.0 * 0.01), st.t));
material.alpha = colorImage.a * color.a;
material.diffuse = (colorImage.rgb+color.rgb)/2.0;
return material;
}`
Cesium.Material._materialCache.addMaterial(
Cesium.Material.PolylineTrailLinkType,
{
fabric: {
type: Cesium.Material.PolylineTrailLinkType,
uniforms: {
color: new Cesium.Color(1.0, 0.0, 0.0, 0.5),
image: Cesium.Material.PolylineTrailLinkImage,
time: 0,
speed: 0.008
},
source: Cesium.Material.PolylineTrailLinkSource
},
translucent: function (material) {
return true
}
}
)
class FlowLine {
constructor(viewer, options) {
this.options = options
this.viewer = viewer
this.id = Cesium.Math.nextRandomNumber()
if (options.id) {
this.id = options.id
}
}
play() {
this.loopMaterial = new PolylineTrailLinkMaterialProperty(
defaults(this.options.color, Cesium.Color.WHITE.withAlpha(0.5)),
defaults(this.options.speed, 0.001),
defaults(this.options.duration, 1750),
defaults(this.options.image, "/guangpu.png")
)
this.line = this.viewer.entities.add({
name: "flowline_" + this.id,
polyline: {
positions: this.options.positions,
width: defaults(this.options.width, 10),
material: this.loopMaterial //修改抛物线材质
}
})
}
destroy() {
if (this.line) {
this.viewer.entities.remove(this.line)
}
}
}
function defaults(value, defaultData) {
return value ? value : defaultData
}
export {
FlowLine
}