Google Pixel 5 手机通过 Magisk unroot 时报错 Stock backup does not exist

  之前用 Magisk 对 Pixel 5 进行过 root,是通过命令 fastboot flash boot /path/to/magisk_patched_[random_strings].img 刷入 Magisk 打过 patch 的 boot.img 文件进行的。目前刷新操作系统前,最好先去除 root 权限(unroot)。但在 Magisk 应用中,选择 Uninstall -> Restore image 时,报错 Stock backup does not exist! ,看来是之前备份的原始镜像文件找不到了。

  解决办法:参考这篇帖子 Fix magisk stock backup does not exist ,通过 adb 运行下面的所有命令。之后就可以从 Magisk 中 Restore image,重启,系统即可恢复到没有 root 的状态。

# put stock boot.img into /sdcard/boot-stock.img

# get sha1
adb shell
su
SHA1=$(cat $(magisk --path)/.magisk/config | grep SHA1 | cut -d '=' -f 2)

# repack boot.img.gz
gzip -9f /sdcard/boot-stock.img

# restore backup
mkdir /data/magisk_backup_${SHA1}
mv /sdcard/boot-stock.img.gz /data/magisk_backup_${SHA1}/boot.img.gz
chmod -R 755 /data/magisk_backup_${SHA1}
chown -R root.root /data/magisk_backup_${SHA1}

西安电信宽带开启IPv6通过Kodi观看IPTV

  书接上篇《解决电视上KODI播放IPTV时无法识别IPV6地址的问题》,在西安家中电视上安装Kodi软件后,发现使用IPv6地址的电视台都无法观看,而IPv4的地址电视台正常,电脑上IINA软件测试也是如此,说明可能是家里宽带的问题。通过 https://test-ipv6.com/ 测试,发现果然没有IPv6网络地址。

  家里是电信宽带,光猫桥接,小米路由器直接拨号。首先到路由器里查看,“IPv6网络设置”并没有开启,于是开启后设置为“Native模式”(适用于路由器拨号;如果是光猫拨号,需选择“NAT6模式”),重新拨号,但还是没有IPv6的连接,问题可能在电信宽带的局端设置上。

  目前运营商都在推广IPv6,所以西安电信本身可能是支持的。于是抱着试试看的心态先尝试修改光猫的设置。家里的光猫管理页面如下:

  按照光猫背后印刷的普通用户登入发现并没有相关设置,可能需要光猫的管理员权限登陆才行。在网上找到一些电信光猫的“破解”教程,还没用到浏览器开发者工具或隐藏登录页的方法,发现用下面默认的用户名密码从默认页面就可以直接登陆了:

中国电信:telecomadmin / nE7jA%5m
中国联通:CUAdmin / CUAdmin 或 CUadmin
中国移动:CMCCAdmin / aDm8H%MdA 或 CMCCAdminWoTf6&$7

  管理员用户登录后,可以看到更多设置选项。只需在网络->网络设置->网络连接中,将IP模式从IPv4改成IPv4&IPv6,保存之后可以在光猫的网络侧信息中看到IPv6的信息。

  然后小米路由器重新拨号,看到路由器已经获取到了IPv6的网络地址,测试IPv6连通性也可以通过,电脑/电视上观看IPTV,所有IPv6地址的电视台也可以正常工作了。

解决电视上KODI播放IPTV时无法识别IPV6地址的问题

  前一段时间《广电总局出手整治电视直播乱象,提升用户体验 》,提升的结果就是电视上一直在用了几年的“电视家”和“火星直播”两个看电视的软件,再也看不了电视了。家里办的宽带虽然附带有IPTV,但需要多一个盒子,多一个遥控,占用一个电视HDMI接口,更无法忍受的是必须连接光猫自带的WiFi热点,整个流程上的所有环节都极不优雅。

  为了在电视上不用IPTV的盒子观看IPTV,可以在KODI软件里安装IPTV插件,搜索关键字“kodi iptv设置”。大致步骤如下:

  • 设置->插件->从库安装->PVR 客户端->安装 PVR IPTV Simple Client。
  • 之后设置插件:插件->我的插件,找到刚安装的PVR IPTV Simple Client,设置中添加一个配置文件。其中M3U8播放源选择”远程路径“(指向一个https://开头的在线地址,播放源由维护者自动更新)或”本地路径“(指向比如NAS上的.m3u文件,播放源需手动更新)都可以。配置后可能需要重启KODI以生效。
  • 最后在“电视直播”中就可看到所有更新的电视节目。

  这里推荐两个我自己测试了一段时间的源,感谢维护的作者。包含央视,所有卫视,和一些国外的频道节目:

  但在电视上KODI播放时,发现了一个问题:有些节目可以正常播放,有些则不能播放,报错“一个或多个项目播放失败。更多相关信息见日志。”,类似 https://www.right.com.cn/forum/thread-8265882-1-1.html 。测试macOS的IINA软件中打开同样的.m3u文件,所有频道可正常播放。查看.m3u内容,发现无法播放的频道全部是IPV6的地址。电脑可以播放说明网络环境是支持IPV6的,问题在KODI软件里。最终搜索到了网友x3669的提供的解决办法(链接1链接2:在IPV6的源上,手动添加80端口。比如:

  • cctv1原地址:http://[2409:8087:2001:20:2800:0:df6e:eb03]/ott.mobaibox.com/PLTV/4/224/3221227896/index.m3u8
  • 修改后地址:http://[2409:8087:2001:20:2800:0:df6e:eb03]:80/ott.mobaibox.com/PLTV/4/224/3221227896/index.m3u8

  保存成.m3u文件放到NAS上,KODI中读取修改后的.m3u文件所有频道即可正常播放。为了自动更新在线的播放源到本地文件,请ChatGPT写了一个bash脚本,在家里另一个Linux机器上crontab每30分钟运行一次即可:

#!/bin/bash

# 设置下载URL和NAS存储路径
URL="https://raw.githubusercontent.com/YueChan/Live/main/IPTV.m3u"
NAS_PATH=""  # NAS上的存储路径
NAS_USER=""  # 请替换为您的NAS用户名
NAS_IP=""  # 请替换为您的NAS IP地址

# 下载最新的.m3u文件
wget -O IPTV.m3u $URL

# 检查文件是否下载成功
if [ ! -f IPTV.m3u ]; then
    echo "Failed to download file."
    exit 1
fi

# 修改文件内容
sed -i 's/]\//]:80\//g' IPTV.m3u

# 检查文件是否修改成功
if [ $? -ne 0 ]; then
    echo "Failed to modify file."
    rm IPTV.m3u
    exit 1
fi

scp -i /root/.ssh/id_rsa_nas IPTV.m3u "$NAS_USER@$NAS_IP:$NAS_PATH"

# 检查文件是否成功传输
if [ $? -ne 0 ]; then
    echo "Failed to transfer file to NAS."
    exit 1
fi

echo "Operation completed successfully."

威联通 NAS 中使用 Nginx Proxy Manager 反向代理多个 docker 应用

  前一阵在威联通 QNAP 的 NAS 中通过 docker 安装了 ChatGPT-Next-Web 这个项目,给朋友分享ChatGPT使用,但这个 web 项目本身不涉及SSL证书的配置,于是应用一直跑在未加密的 HTTP 协议下;加上之前的另一个 docker 媒体播放应用 Jellyfin,目前已经在路由器上设置了多个端口转发,需要通过记忆特定端口来打开对应的应用。有没有什么办法能同时解决这两个问题呢?显然 Nginx 来做反向代理再合适不过了。但这次跳过手写配置文件,我们使用 Nginx Proxy Manager 来达到目的。

目的

  现状:

  要实现的目的:

  • docker中运行的应用都可以通过 HTTPS 方式访问。
  • 通过不同的(子)域名访问对应的应用,方便记忆。比如: https://chat.mydomain.com:7443 打开 ChatGPT 应用, https://jellyfin.mydomain.com:7443 打开 Jellyfin 应用。
    • 注:因为运营商屏蔽 80 和 443 端口,所以你需要选择一个非默认端口来打开你的应用。

具体步骤

1. docker 安装 Nginx Proxy Manager 。我这里使用 docker compose 方式如下:

version: '3.3'
services:
  nginx-proxy-manager:
    container_name: nginx-proxy-manager
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '9080:80' # 监听的 HTTP 端口
      - '9081:81' # 管理页面的端口
      - '9443:443' # 监听的 HTTPS 端口
    volumes:
      - /share/Container/nginxProxyManager/data:/data
      - /share/Container/nginxProxyManager/letsencrypt:/etc/letsencrypt 

2. 通过 http://<nasIP>:9081 登陆 Nginx Proxy Mananger,SSL Certificates 页面给想要分配给应用的域名申请 SSL 证书。

  • 默认用户名密码是 admin@example.com/changeme,首次登陆需要修改。
  • mydomain 是你提前注册好的域名。我的域名托管在 CloudFlare,所以 DNS Provider 处选择 Cloudflare;另外需要在 CloudFlare 提前设置好 API token 填入下图对应位置。

3. 将你的域名 DNS 记录解析至家里 NAS 的 DDNS 地址。比如我在 CloudFlare 对应域名的 DNS 设置中,添加了两个子域名 chat.mydomain.com 和 jellyfin.mydomain.com,都通过 CNAME 记录指向我的 DDNS 地址 https://mydns.myqnapcloud.com 。之后通过这些域名和特定端口的请求会被运行的 Nginx Proxy Manager 接管。

4. Nginx Proxy Manager 的 Hosts 页面,添加 New Proxy Host。Forward Hostname / IP 和 Forward Port 是你内网应用运行的地址和端口,Nginx Proxy Manager 会将此域名的请求转发到这个应用。其中 SSL tab 页的 SSL Certificate 选择步骤 2 中申请号的泛域名证书。

5. 最后到路由器中设置端口转发,允许特定外网端口转到 Nginx Proxy Manager 监听的端口。比如我所有应用都强制 HTTPS 访问,则只需转发上面 docker compose 文件中的 9443 端口到外网 7443 (可随意修改)即可。

  至此设置完毕。

遇到的问题和解决办法

  此时发现通过 https://chat.mydomain.com:7443 并不能打开内网的 ChatGPT 应用,等待之后显示 504 Gateway Time-out openresty 错误。但如果通过路由器端口转发,直接访问 ChatGPT 应用或 Nginx Proxy Manager 管理页面都是没有问题的,证明这两个应用本身可以独立运行。
进入 Nginx Proxy Manager docker 的控制台,查看 /data/logs 下的 _error.log 和 _access.log 文件,发现提示上游请求无法通过;另外通过 curl 命令打到内网 ChatGPT 应用地址发现无响应。判断是 Nginx Proxy Manager 的 docker 和其它 docker 应用无法通信。
  查看威联通的”网络与虚拟交换机“,发现自己通过 docker compose 方式创建的应用,都分别使用了独立的虚拟交换机并且网段不同;而如果通过 Container Station UI 创建的 docker 应用,则都会默认连接到名为 lxcbr0 的同一个虚拟交换机中,可以互相通信。因此只需将 docker compose 创建的应用,接入同一个网络中即可。
  为此,首先 SSH 到 NAS 主机中,通过 docker network create my-custom-network 命令在 docker 中创建一个新的网络。之后在需要连接到此网络的应用的 docker compose 文件中加入对应的 networks 配置。修改后的 Nginx Proxy Manager docker compose 文件如下:

version: '3.3'
services:
  nginx-proxy-manager:
    container_name: nginx-proxy-manager
    image: 'jc21/nginx-proxy-manager:latest'
    restart: unless-stopped
    ports:
      - '9080:80'
      - '9081:81'
      - '9443:443'
    volumes:
      - /share/Container/nginxProxyManager/data:/data
      - /share/Container/nginxProxyManager/letsencrypt:/etc/letsencrypt
    networks:
      - my-dockers-network

networks:
  my-dockers-network:
    external: true

  同样修改 ChatGPT 和 Jellyfin 应用的 docker compose 文件,添加上面最后几行 networks 的设置并重启后,”网络与虚拟交换机“里可以观察到几个 docker 应用接入了同一个虚拟交换机。此时通过不同域名加固定端口号的方式,便可以分别访问对应的应用了。

自动更新 AWS Lightsail 实例的公网 IP 地址并同步到 Cloudflare 的域名 DNS 记录

  近几个月来科学上网的环境持续不稳定,即使方式从 v2ray 的 websocket+tls 换成了 xray 的 vless+xtls-rprx-direct 配置,印象中去年底开始,刚刚更新好的上网环境,包括自建和订阅,用一阵以后(几天时间不等)也会断流继而彻底失效。

  经过观察发现,如果是自己搭建的环境,刚开始ping域名是可以返回背后的 IP 地址,但断流失效后,ping域名就没有响应了;此时 VPS 里的相关服务是持续稳定的,所以可能是 VPS 的 IP 地址被加入了“黑名单”。这时如果更换 VPS 的 IP 地址,并重新绑定到先前的域名,上网环境又重新可用,如此往复。这篇文章针对自建环境的情况,分享一种解决目前问题的方法。对于订阅的情况,只要更新一次订阅的服务器节点即可。

  根据上面的思路,只需要定期自动更新 VPS 的外网 IP 地址,然后同步到自己域名的 DNS 解析记录即可。我目前使用的是 AWS Lightsail 和 Cloudflare,在 Linux 环境里解决问题的具体步骤如下。如果你使用其它服务商,需要查询一下相关的 API。

1. 安装和配置 AWS CLI

  AWS Lightsail可以看作是廉价的EC2服务,因此其实例同样可以用AWS CLI来进行操作。安装只需要依次执行以下命令:

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

  完成之后需要使用 aws configure 命令配置安全认证以便能够和你的 Lightsail 交互。这里需要提前创建好 IAM 用户和 access key。参考步骤和文章:

2. 用 AWS CLI 更新 Lightsail 实例的 IP 地址

  在 Lightsail 控制台界面上操作时只需要删除掉目前的静态公网 IP 地址并重新创建一个新的地址即可,创建过程中可以顺便绑定到你的实例机器。同样的过程用命令行操作,需要依次输入以下命令:

  1. 根据名称删除当前的 IP 地址 aws lightsail release-static-ip --static-ip-name StaticIp-1
  2. 申请新的 IP 地址并命名 aws lightsail allocate-static-ip --static-ip-name StaticIp-1
  3. 将新的ip绑定到指定的实例上 aws lightsail attach-static-ip --static-ip-name StaticIp-1 --instance-name Ubuntu2004LTS-Tokyo1

  参考 https://docs.aws.amazon.com/cli/latest/reference/lightsail/index.html

3. 利用 Linux shell 脚本更新 Cloudflare 中域名的 DNS 记录

  这一步在之前文章“OpenWrt中通过自定义脚本为Cloudflare域名更新DDNS“中有具体内容,此处略过。这里给出完整的脚本供参考。

  上面步骤2中的命令有些需要用户输入才能继续,因此脚本里禁用了 AWS CLI 的输出以便可以自动执行。

4. 定时自动执行以上脚本

  在稳定的 Linux 环境中 crontab -e 将上述脚本加入 cron 任务定时运行。比如我这里是每天早上6点执行一次:

0 6 * * * /root/updatePublicStaticIPForLightsailAndCloudflare.sh

  尾巴:如果问为什么要同时使用自建和订阅服务,考虑的因素有两点:1. 隐私安全;2. 鸡蛋不放在一个篮子里,避免需要“初始化”上网环境时,无法“上网”的窘境。

OpenWrt中通过自定义脚本为Cloudflare域名更新DDNS

  在上一篇文章中,威联通NAS上myQNAPcloud DDNS获取外网地址不准确的问题,提到使用myQNAPcloud服务来设置DDNS。这次尝试不依赖QNAP的服务,在OpenWrt里定时运行自定义脚本来直接更新域名的DNS地址。

  我的域名托管在Cloudflare上,所以主要思路是定时在OpenWrt里运行脚本检测公网IP地址是否有变化,如果有就用Cloudflare的token和API来更新相关DNS设置。

  记录具体步骤如下:

  1. 获取Cloudflare的API token,稍后脚本中会用到。进入 https://dash.cloudflare.com/profile/api-tokens 页面,Create Token,为了使token权限最小化选择Create Custom Token,设置如下图。Specific zone选项可限制token权限为仅允许更新某一个域名。
  2. 在上面所选域名的DNS设置中,添加一条A记录,设置成DDNS想要绑定的域名。IP地址随意设置比如8.8.8.8(之后脚本会付覆盖),Proxy status设置为DNS only。
  3. OpenWrt运行的脚本。参考了一些网上的脚本,发现 https://raw.githubusercontent.com/K0p1-Git/cloudflare-ddns-updater/main/cloudflare-template.sh 这个脚本比较全面(下载链接),注释也清楚。几点注意事项:
    • 第一行的#!/bin/bash需要修改成#!/bin/sh,否则OpenWrt中没有bash环境无法运行。
    • 要填写的项目有auth_email,auth_key,zone_identifier,record_name,其余可留空。
    • auth_method="token" 注意保持token方式,对应步骤1中创建的API token。同一页面还可看到Cloudflare的Global API Key,因为它可以操作账户里的所有设置,不建议使用。
    • 如果OpenWrt设置了科学上网/透明代理,curl -s -4 https://cloudflare.com/cdn-cgi/trace运行时可能获取到代理服务器的ipv4地址。可以注释掉相关if判断部分,改为用其它API直接获取,即ip=$(curl -s https://api.ipify.org || curl -s https://ipv4.icanhazip.com) 。注:此地址需添加到科学上网的“不走代理域名”列表内,否则全局代理时,访问这些地址获取到的也变成了代理地址。
  4. 用scp命令将修改好的脚本上传到/root目录,chmod +x updateDDNS_cloudflare.sh赋予执行权限。先手动运行一次观察输出是否正常/bin/sh -x updateDDNS_cloudflare.sh。如果脚本运行无误的话,可以在Cloudflare中观察到对应A记录的DNS更新成功。
  5. crontab -e编辑计划任务,添加一行内容*/10 * * * * /root/updateDDNS_cloudflare.sh,这样此脚本会每10分钟运行一次以按需更新DDNS。此步骤也可在OpenWrt网页端的“系统->计划任务”里完成。

  其实同样的工作也可以在OpenWrt的web管理页面上完成,如果你可以在“服务->动态DNS->DDNS 服务提供商 [IPv4]”的设置中找到Cloudflare选项的话。我用的OpenWrt编译了动态DNS的应用(luci-app-ddns, ddns-scripts),但没有Cloudflare的入口点。尝试安装ddns-scripts-cloudflare或更早的ddns-scripts_cloudflare.com-v4_2.7.8-3_all.zip,不仅依然找不到Cloudflare入口点,还有可能破坏掉OpenWrt:实际后台依然运行,可以上网,但web页面(LuCI web interface)报错Bad Gateway The process did not produce any response.,只能借助ESXI里的快照恢复或重新安装OpenWrt。所以才有了这篇博客。

威联通NAS上myQNAPcloud DDNS获取外网地址不准确的问题

  威联通(QNAP)NAS上自带的myQNAPcloud服务可以识别到NAS所在网络的外网地址,从而和你注册的QNAP域名(*.myqnapcloud.com)绑定,方便从外网通过该域名访问NAS服务。

  问题:最近发现家里的两台NAS中,一台的myQNAPcloud服务可以识别正确外网地址,而另一台NAS识别出的外网地址不对,实际上是软路由里科学上网的代理地址。猜测有问题的这个NAS不知为什么通过代理访问了myQNAPcloud的服务器。

  解决办法:在软路由的代理设置中,将访问myQNAPcloud服务器的地址 edge.api.myqnapcloud.com 设置成不走代理即可。

myQNAPcloud服务器地址加入不走代理设置

参考文章:

关于给黑洞拍照背后的故事

  黑洞——人类当前认知中最神秘的宇宙天体。100多年前爱因斯坦的广义相对论就预测到它的存在,但直到2019年4月人类才获得了第一张黑洞照片。能够给黑洞拍照无疑是解锁了人类科技树上的新技能,如果你也和我一样好奇的话,本文就和大家分享一些给黑洞拍照背后的故事。

1. 当我们给黑洞拍照时,我们在拍什么?

  黑洞本身并不发光,也不会向外发出任何电磁辐射(除了还未被证实的霍金辐射),即使以宇宙中最快的光速运动也无法逃脱它的引力束缚。那对着它拍照岂不是什么也看不到?黑洞照片上那朦胧的橘色轮廓又是什么?要想知道给黑洞拍照的真相,我们先回顾一下黑洞的结构。

  根据上面这张欧洲南方天文台(The European Southern Observatory,简称ESO)给出的假想图可以看出,一个典型黑洞是由奇点,事件视界,光子球,相对论性喷流,最内侧稳定轨道,吸积盘等组成。简单来说,黑洞有两个最基本的部分。第一个是奇点(singularity),即黑洞的中心点,也是落入黑洞物质命运的终点。这是一个体积无限小,密度无限大的引力异常点,此处的空间和时间已经被扭曲到所有的已知物理定律,包括预言它存在的广义相对论都不再适用;第二个是事件视界(event horizon),可以把它理解成一个无形的边界,在这个边界上逃逸速度正好等于宇宙中最快的光速,所以一旦进入这个边界内部,就再也无法逃出黑洞。在万有引力常数不变的情况下,逃逸速度只和物体的质量还有半径(体积)有关。地球的逃逸速度即第二宇宙速度是11.2千米/秒。如果把地球压缩到半径9毫米以下的体积,那么它的逃逸速度就会大于光速,也就变成了一个黑洞。这个临界值可以简单理解为是任何物体自身的事件视界到奇点的距离即史瓦西半径,如果把一个物体压缩成球体的话,只要半径小于史瓦西半径,它就可以变成一个黑洞。太阳的史瓦西半径是3千米,一个人的史瓦西半径大概是10-26米(比电子还要小一亿倍)。

  黑洞在“吞噬”其周围物质时会形成高速旋转的吸积盘(accretion disc)。它是黑洞周围的气体或尘埃受到黑洞引力影响跟着一起旋转,当其角动量足够大即旋转足够快时,在一些特定的位置,产生的离心力能够和黑洞的引力相抗衡,从而形成的一种盘状结构。吸积盘内的气体因为高速旋转会产生超高温,从而向外辐射大量能量,也就是人类观察到黑洞发出的电磁波的主要来源。当黑洞吸积物质过快时,吸积盘的磁场会沿着黑洞自转方向扭曲,一些粒子就会以极高的动量(甚至接近光速)喷射出去,形成相对论性喷流(relativistic jets)。

  因此,给黑洞拍照主要是在不可见光波段,观测黑洞的吸积盘及喷流产生的电磁辐射。

2. 人类迄今为止拍摄到唯二的黑洞照片

  截至目前,人类只拍到过两张黑洞照片,都是由事件视界望远镜(Event Horizon Telescope,简称EHT)组织拍摄、整理、发布。EHT成立于2009年,专门以观测拍摄黑洞为使命,目前由超过20个国家和地区,60个科研机构的300多名科学家组成。

  这两张照片分别是2019年4月10日发布的Messier 87(室女A)星系中心超大质量黑洞(简称M87*)照片,以及2022年5月12日发布的我们银河系中心人马座A(Sagittarius A)方向的超大质量黑洞(简称Sgr A*或银心黑洞)照片。这里的星号借鉴了原子物理中激发态(excited state)的概念,表示该天体处于非常活跃的状态。

  两图中心黑色阴影部分并不是事件视界的范围,而是大约黑洞史瓦西半径的2.6倍大小,橘色亮斑代表吸积盘上的气体向着接近我们的方向旋转,暗部则反之(多普勒效应)。至于为什么银心黑洞上有三个亮斑,目前还未能确认其产生原因。

  下面是这两个黑洞的一些基本情况:

 M87*Sgr A* 银心黑洞
质量(与太阳相比)65 亿 410
与地球的距离5300 光年26600 光年

  再看看两个黑洞的大小。下图中右侧中心的小白点是太阳,银心黑洞外围(吸积盘)的面积,与水星轨道面积相当;左侧是M87*,图中白色小圆圈是冥王星的轨道面积,白色小点是1977年发射的旅行者1号,目前距离地球最远的人造探测器的位置。

  如果上面的表格中数字太大或黑洞体积还是不直观的话,我们把太阳放大看看可能会容易理解一些。

  实际上这两张黑洞照片的“拍摄”时间都是在2017年4月,持续近10天。第一张M87*照片在两年后公布,第二张银心黑洞的照片又等了3年才公布。

3. 给黑洞拍照很难吗?

  现在你可能会问,这两个黑洞那么大,怎么还拍得这么不清楚?和《星际穿越》里黑洞的样子相比怎么这么难看?给它们拍照片很难吗?答案是:难,非常难。可谓是拍照10天,修图5年(银心黑洞)。

挑战一:角分辨率

  从距离上来说,M87*黑洞虽然距地球比银心黑洞远2000倍,但却比后者要大1000倍。所以从地球望去,视觉效果上两者是差不多大小的。加之一个是我们已知的最大黑洞之一,一个是我们自己星系中心的黑洞,因此EHT选择它俩作为观测目标。它们在天空占据多大的位置(角分辨率)呢?答案是52微角秒(1微角秒=1″ / 1000 / 1000 ),相当从地球观察月球表面一个甜甜圈????。经计算,望远镜的尺寸需要和地球一样大,才可以达到如此的拍摄分辨率。

挑战二:超大数据量

  对黑洞的观测每天每个观测点产生的数据量可达350TB,科学家们需要足够的耐心和时间来处理这些数据。

银心黑洞附加题一:尘埃带遮挡

  由于太阳系位于银河系的盘面上,向银河系中心望去时,存在很多遮挡物,这是由星际尘埃和气体组成的尘埃带,使得银心处的可见光,紫外线和部分X射线都无法到达地球。尘埃带一般常见于漩涡星系或棒旋星系(比如银河系)。而M87星系是椭圆星系,完全不受银河系尘埃带遮挡,加上观测路线上也比较通透,所以后期数据处理要容易很多。

银心黑洞附加题二:延时摄影

  虽然两个黑洞的吸积盘旋转都非常快速(甚至接近光速),但因为M87*体积足够大,因此吸积盘旋转一圈需要数天时间,而银心黑洞吸积盘旋转一圈的时间只需要数分钟。这就导致给银心黑洞拍照类似延时摄影,或在光线不好的地方给一条欢乐的小狗拍照,很难得到一张清楚的照片。

4. 如何给黑洞拍照?

  好在人类拥有足够的好奇心和智慧的科学家们。在EHT 300多名工作人员跨地区跨时区的努力下克服了重重困难,最终让我们看到了宇宙中最神秘天体的样貌。

  为了建造足够大的望远镜,科学家们利用了甚长基线干涉(very-long-baseline interferometry, 简称VLBI)技术。简单地说,就是将地球上不同位置的射电望远镜组成一个虚拟阵列,并通过原子钟记录观测时间/同步数据,最终虚拟出一个相当于地球大小口径的望远镜。该望远镜的角分辨率达到了20微角秒,足够从巴黎看清楚纽约一张报纸上的文字。

  2017年4月的观测活动共有8个观测站参加,持续近10天。对于每天每个观测点350TB的数据,最终是由飞机将硬盘分别运送到德国的马克斯普朗克射电天文研究所和美国麻省理工学院海斯塔克天文台,由两地的超级计算机通过后期复杂的算法分别合并处理。

  此外,EHT团队利用每次观测时间的一部分来建立模型,使得最终可以去除地球大气湍流(从地面向天空拍照的反向去云)和尘埃带对银心黑洞数据的影响。

  对于银心黑洞因为吸积盘旋转过快造成的“延时摄影”的问题,从下图可以看出,不同于右侧M87*多张图像比较近似,左侧银心黑洞几乎每张图像都有差异。研究人员将4组平均后的图像再次合成,得到了最终银心黑洞的照片。

5. 给黑洞拍照有什么意义?

  虽然黑洞最早是由广义相对论预言存在的,但爱因斯坦本人一开始也无法相信这种天体的存在;即使到今天,天文学家普遍认为大多数星系中心几乎都存在一个超大质量黑洞,但就在2020年诺贝尔物理学奖颁给研究银河系中心的根策尔和盖兹时,也严谨地用了“超大质量致密天体”而不是黑洞的表述。

  如今人类解锁了给黑洞拍照的技能,不仅直接证明了星系中心黑洞的存在,其观测结果也与广义相对论的预测惊人地吻合,再次验证了它的正确性。通过对黑洞的观测和分析,不仅能让我们更加了解这种目前宇宙中已知的最神秘的天体,也会帮助我们更多了解星系演化的过程。

  顺带一提的是,通过一项对银河系中心长达16年的研究,科学家们还绘制出了近30颗恒星围绕银心黑洞的运行轨迹。不仅如此,其中一颗名为S2的恒星,在距离银心黑洞最近点(不到200亿千米)处的移动速度达到了惊人的2500万千米/时,接近光速的3%。如果单看其中一个的话,正如广义相对论所预测的那样,它的轨道形状成花瓣状,而非牛顿引力理论所预测的椭圆形,这是由史瓦西进动效应造成的。下图是艺术家展示的恒星围绕黑洞运行的轨道图(为了更好的视觉效果有所夸大)。

  但请不要误以为银河系中心就是这种唯美的画风,实际上它远比我们想象的要“暴力“许多。下图是美国国家航空航天局(简称NASA)2021年5月公布的一张由钱德拉 X 射线天文台和南非MeerKAT射电望远镜共同观测的银河系全景图,它主要是由不同X射线波段的数据合成而来。其中包括了炽热气体喷流,各种磁场线,以及中间白色部分的银河系中心。

6. 彩蛋:黑洞是如何形成的?

  黑洞的分类方法一般有两种:按照黑洞本身的物理特性(是否旋转,是否带电)分类和更常见的按照其质量体积分类。人类目前研究最多的两种黑洞就是按照质量来分类的恒星级黑洞(stellar black hole,5至数十倍太阳质量)和超大质量黑洞(supermassive black hole)。

  对于恒星级黑洞的形成原因,简单来说它是由大质量恒星生命末期经历超新星爆炸(supernova)后由引力坍缩形成的。而超大质量黑洞,其质量可达太阳质量的10万倍乃至100亿倍,对于其成因目前还没有比较确定的理论。

恒星级黑洞的形成

  恒星诞生是因星云内光年范围的气体和星际尘埃被扰动,物质不断向中心聚集,随着温度和压力的升高旋转坍缩而形成(剩下的“边角料”吸积会形成行星)。恒星诞生后内部主要存在两种力:自身质量产生的引力和由氢元素核聚变成氦元素过程中产生向外的推力。在主序星(main sequence star)阶段,这两种力维持平衡状态。当恒星进入生命演化末期后氢元素耗尽,意味着到氦元素的核聚变和向外的推力停止,但其自身的引力并不会消失,所以这种平衡被打破,其内核部分会像当初诞生时一样被引力压缩,内部温度和压力不断增加。当超过某个界限时,氦元素就会开始进一步核聚变。这种新的推力会使恒星的体积变成稳定时的几十倍或上百倍,即红巨星阶段。其内部温度也会高达上亿度,氦元素将快速核聚变直至成为碳元素。之后恒星已经没有足够能量来再次抗衡引力坍缩了,核心以外的外围物质会被抛散到宇宙空间中,但其最终的命运会因其自身质量不同而产生巨大差异。

  • 当恒星的质量小于1.44倍(钱德拉塞卡极限)太阳质量

  电子简并压力就会阻止其核心部分进一步坍缩从而形成稳定的白矮星(white dwarf),我们的太阳在50亿年之后就将面临此命运。推测白矮星会因能量渐渐散失最终变成黑矮星,但此过程需要的时间比现在宇宙年龄137.7亿年还长,因此现实中还没有黑矮星出现过。

  • 当恒星质量大于1.44倍但小于大约3倍左右(奥本海默极限)太阳质量

  由于自身引力过于强大,会使核心部分进一步坍缩。电子会被压入原子核,和带正电的质子中和变成中子,从而演化成中子星,这个过程通常会产生超新星爆炸现象,其亮度可短暂超过所在整个星系的亮度。中子星是除黑洞外密度最大的天体,一立方厘米体积物质的质量可达10亿吨。

  • 更大质量的恒星

  其内部核聚变的过程可以一直到铁元素(到铁元素后,核聚变将不再释放能量而是需要吸收能量)。经历超新星爆炸后,其核心就会进一步坍缩成恒星级黑洞。

  冷知识:根据现有理论,恒星的质量是有上限的,目前已知质量最大的恒星是太阳质量的200多倍。恒星质量越大,通常意味其寿命越短。比如著名的盾牌座UY,虽然其半径大约为太阳的1000倍,体积能容纳50亿个太阳,但质量仅为太阳的7-10倍。

超大质量黑洞形成的猜测

  传统理论认为它是由普通黑洞吸引合并或星系碰撞后中心黑洞合并形成的,但这个过程相对缓慢,不足以解释那些上亿倍太阳质量黑洞的存在。近期也有新的理论认为某些星系中心直接由暗物质构成,当其密度达到临界阈值后会直接坍缩形成超大质量黑洞。最新的詹姆斯韦伯太空望远镜也许能帮助科学家们找到答案。

7. 结语

  就在半个月前,NASA公布了詹姆斯韦伯太空望远镜拍摄的第一组五张图片,虽然顶着鸽王之王的头衔,但这个目前人类最强的望远镜果然没让科学家们失望。它现在正孤单一“镜”地处于地球外侧150万公里的日地拉格朗日点(Lagrangian point ,日地万有引力平衡点)L2附近。如果在将来,人类还能发射新的望远镜们到其它4个拉格朗日点上呢?我们是不是可以继续用VLBI技术得到一个近似地球轨道面积大小的虚拟望远镜?那个时候人类又将寻找怎样的拍摄目标?

  我们现在知道,一颗恒星诞生于超过光年范围的气体和尘埃云,在它数以亿年计的生命中,将宇宙最原始的氢元素不断聚变,直至其消亡时以爆炸这种壮丽的方式将部分金属元素重新抛洒回宇宙空间,可能成为孕育下一颗恒星/行星的原料。这和渺小地球上的生命历程是何其相似。从某种程度上讲,正在拿着手机(含有金属元素)阅读本文的你我,本就是宇宙中的尘埃,而我们手握的却是曾经璀璨的星辰。

  宇宙年龄将近138亿年,可观测宇宙半径为465亿光年,仅银河系内至少就有1000亿颗行星。在如此广袤的宇宙空间和无限的时间中,你我能够共享同一个星球,同一段时光,阅读同一篇文章,是何等的幸运……

参考资料

  1. Astronomers Reveal First Image of the Black Hole at the Heart of Our Galaxy https://eventhorizontelescope.org/blog/astronomers-reveal-first-image-black-hole-heart-our-galaxy
  2. Astronomers reveal first image of the black hole at the heart of our galaxy https://www.eso.org/public/news/eso2208-eht-mw/
  3. Astronomers Capture First Image of a Black Hole https://www.eso.org/public/news/eso1907/
    • 20 micro-arcseconds — enough to read a newspaper in New York from a café in Paris
  4. How Scientists Captured the First Image of a Black Hole https://www.jpl.nasa.gov/edu/news/2019/4/19/how-scientists-captured-the-first-image-of-a-black-hole/
  5. First Successful Test of Einstein’s General Relativity Near Supermassive Black Hole https://www.eso.org/public/news/eso1825/
  6. Magnetized Threads Weave Spectacular Galactic Tapestry https://www.nasa.gov/mission_pages/chandra/images/magnetized-threads-weave-spectacular-galactic-tapestry.html
  7. Stellar evolution https://en.wikipedia.org/wiki/Stellar_evolution
  8. 人類首次拍到的銀心黑洞!如何欣賞第二張黑洞特寫照片? https://www.youtube.com/watch?v=y2_VKxrqLpY
  9. 解開黑洞謎團 https://www.youtube.com/watch?v=ljhgurGJnEQ
  10. What it Takes to Image a Black Hole https://www.youtube.com/watch?v=D3m-GtAt5hY
  11. How did they actually take this picture?  https://www.youtube.com/watch?v=Q1bSDnuIPbo

利用Real-ESRGAN修复制作高清版国产经典动画《大闹天宫》

  之前和儿子看了几次西游记的舞台剧,为了让他对故事的来龙去脉有更完整的印象,答应了和他一起看孙悟空动画片。当然不是白龙马,蹄朝西,而是更久远的 1961 年首映的国产动画《大闹天宫》,至少那时的动画是真的为了做好动画,没有商业目的,看完即走不卖周边可以放心食用。找到了 [大闹天宫(影迷修复版)].The.Monkey.King.(Fan.Restored.Edition).1965.DVDRip.x264.AC3-CMCT.mkv (1.46GB) ,虽然已经是修复版,但画质仍然是比较感人。于是自己也有了这次动画的修复经历。

  修复使用的是 Real-ESRGAN 这个库,它基于 PyTorch 实现,用于对图像进行超分辨率成像 (super-resolution) 。根据作者 xinntao 的介绍,

Real-ESRGAN 的目标是开发出实用的图像/视频修复算法。我们在 ESRGAN 的基础上使用纯合成的数据来进行训练,以使其能被应用于实际的图片修复的场景(顾名思义:Real-ESRGAN)。

  ESRGAN 的作者也是同一人,属于自我进化了。另外作者还提供了论文和详细的 PPT 介绍。这次我用到的是专门针对动漫视频制作了模型的 RealESRGAN AnimeVideo-v3 ,介绍页面中作者已经提供了编译好的各平台可执行文件以及使用步骤,此处就不重复粘贴具体命令了,只对大致过程和遇到的问题说明一下。

  从超分辨率成像的描述可以看出,Real-ESRGAN 的核心是对图像进行“修复”。那么对视频文件如何处理呢?思路和把大象关进冰箱是一样的,总共分三步:

  1. 利用 FFmpeg 把视频中的每一帧图像都抽取出来,类似把视频解压缩成图像。开头提到的《大闹天宫》视频变成了 170,977 张 720*512 的图片文件,总大小 14.33GB。
  2. 使用编译好的可执行文件 realesrgan-ncnn-vulkan 对每帧图片进行增强。我选择的是默认 2 倍分辨率,于是得到了同样数量的 1440*1024 的图片文件,总大小 171.79GB。
  3. 利用 FFmpeg 把增强后的图像文件合并成视频文件,类似把图片打包成视频。最后修复好的两倍分辨率高清版视频是 2.42GB,libx264 编码格式。这里要注意两点:
    • 把图像打包成视频,要使用原始视频文件的fps,即每秒的帧数,也是利用FFmpeg的到。开头提到的《大闹天宫》是25 fps,由此也能推断出视频长度是 170977/25/60≈114分钟。
    • 常见的 mp4 格式只支持 hard subtitles (硬字幕,也等于不支持字幕),也就是把字幕直接合并到每帧图像上,播放时就不能开关或切换字幕了。所以此处我选用了 mkv 格式,一并把原来的简体和繁体中文两种字幕拷贝到了新的视频中,播放时可以按需切换或关闭。具体命令是 ffmpeg -i out_frames/frame%08d.jpg -i dntg.mkv -map 0:v:0 -map 1:a:0 -map 1:s -c:a copy -c:s copy -c:v libx264 -r 25 -pix_fmt yuv420p output_w_audio.mkv ,大致意思是视频按照 libx264 格式每秒 25 帧合并,音频从dntg.mkv文件中直接拷贝,字幕也是从 dntg.mkv 文件中拷贝所有可用字幕。可参考 FFmepg 的 -map 参数

  下面是美猴王孙悟空出场时一帧图像的对比,左侧是原视频中的图像,右侧是修复后视频中的图像。可以看出效果还是很不错的。

  GitHub 介绍中可看到作者 xinntao 是在腾讯工作,在腾讯视频上还能找到已经修复的一些动画片,有《爱探险的朵拉》,《巴布工程师》等。仅在动画领域就可以使小朋友的童年回忆变得更美好一些,在此对作者表示感谢。

  最后儿子问,孙悟空七十二变的本领是怎么学来的?他表示有兴趣学习……

通过威联通NAS上的WireGuard VPN连接回家里的网络环境

  以前在外访问家里NAS内容时,都是通过路由器上的端口转发,登陆NAS管理页面。这样做一是有一定安全隐患,二是所有内容都在NAS管理网页这个”沙盒“里,无法通过本地应用直接访问。比如听歌,要么用NAS自带的网页播放器,要么需要先把歌曲文件下载到本地。最近趁618低价,新添了 QNAP 威联通 NAS TS-464C,今年的网红N5105 CPU配上32G内存(虽然官方硬件规格说最大支持16G内存),足足比14年使用至今的QNAP 212P的512M内存大了64倍……212P虽慢但稳定异常,目前依旧继续服役稳定输出。

  解决上面提到的安全和内容访问问题,标准答案就是VPN,连通后无论身处何地,你的设备就像连到家中的WIFI一样。目前QANP的操作系统QTS 5.0自带了QVPN Service 3软件,内建提供QBelt(QNAP自家标准),PPTP,L2TP/IPSet(PSK),OpenVPN,WireGuard共5种VPN服务。参考NordVPNQNAP自家页面,Wire Guard在安全性和传输速度方面表现都相对更好。

VPN protocolSpeedEncryptionStreamingStabilityP2P
OpenVPNFastVery goodGoodGoodGood
IPSec/IKEv2FastGoodGoodVery goodGood
WireguardVery fastVery goodGoodVery goodGood
SSTPMediumGoodMediumMediumGood
L2TP/IPSecMediumMediumPoorGoodPoor
PPTPFastPoorPoorGoodPoor
VPN协议比较

  于是这次就用QVPN Service搭建WireGuard VPN服务。具体步骤此处省略,可参考QNAP官方文档:How to Configure WireGuard VPN Server and Client Settings in QVPN Service 3。搭建好后,QVPN Service服务器端和Android客户端设置分别如下:

  有几点注意事项分享如下:

  • 服务器端
    • 如果NAS里启用了QNAP的防火墙QuFirewall,请参照How to setup QuFirewall to allow VPN connections设置以允许WireGuard服务通过防火墙。
    • 需要在路由器上做端口转发以允许外网访问WireGuard VPN服务。上图使用的是默认端口51280。
  • 客户端
    • 接口的地址需要填入服务器端对等表中分配好的“允许的IP”地址。服务器端的对等表,建议一个设备添加一条记录方便区分。
    • 对等中的端点地址,填入通过路由器转发的WireGuard服务外网地址端口。
    • 对等中的允许IP地址,填入0.0.0.0/0以允许所有IP地址的流量。

  至此,你应该可以随时随地通过WireGuard服务接入家中的网络环境了。经过几天测试使用,速度和稳定性都很不错。在外面通过4G网络加WireGuard给小朋友看家中NAS里的《绿色星球》很流畅。另外因为等同接入家中WIFI,家里软路由上运行的所有服务也都是可以直接使用的,比如访问国际互联网。

  这次虽然使用的是QNAP自带的QVPN Service软件,但理论上在NAS的docker中或软路由(docker)中运行WireGuard服务器端都是可以的。

  总结一下使用WireGuard VPN服务接入家中网络的一些特点:

  • 连接速度和安全性都有保证。
  • 可通过客户端本地软件访问NAS内容,比如电影和音乐,不受网页端限制。
  • 以下两点,对于家里其他成员非常方便。一人维护家里的设置,所有客户端一次性配置免去今后维护,对于外地家庭成员尤其友好:
    • 可以替代NAS本身的网页“分享链接”功能。比如外地的家中成员看NAS里的电视剧时可以摆脱网页播放器,从而使用平板或手机的本地播放器进而投射到电视大屏上。
    • 可以直接使用软路由上的服务访问国际互联网,比如备份照片到Google Photos里。
  • 依然需要保留NAS网页端直接访问功能,以便在已经连入其它VPN的情况下访问NAS。