Streaming Protocol & Streaming Coding

流式传输 协议

常用的流媒体协议主要有两类:

  • HTTP渐进下载
  • 基于RTSP/RTP的实时流媒体协议。

在流式传输的实现方案中,一般采用

  1. HTTP/TCP来传输控制信息,
  2. 用RTP/UDP来传输实时多媒体数据。

RTP 、 RTCP (Real-time Transport Control Protocol)

  • 由IETF的多媒体传输工作小组1996年在RFC 1889中公布。
  • RTCP是RTP的一个姐妹协议
  • RTP协议的特点
    • RTP协议是建立在UDP协议上的。
    • RTP并不保证传送或防止无序传送,也不确定底层网络的可靠性。
    • RTP实行有序传送,RTP中的序列号允许接收方重组发送方的包序列。
    • RTP不像http和ftp可完整的下載整個影視檔,它是以固定的資料率在網路上發送資料,用戶端也是按照這種速度觀看影視檔,當影視畫面播放過後,就不可以再重複播放,除非重新向伺服器端要求資料。
  • RTCP特点
    • RTCP的主要功能是为RTP所提供的服务质量提供反馈来试图提高服务质量。RTCP收集相关媒体连接的统计信息,例如:传输字节数,传输分组数,丢失分组数,时延抖动,单向和双向网络延迟等等。来判断是否限制信息流量或改用压缩比较小的编解码器。
    • RTCP本身不提供数据加密或身份认证,其伴生协议SRTCP安全实时传输控制协议则可用于此类用途。

SRTP & SRTCP(Secure Real-time Transport Protocol)

  • 最早由IETF於2004年3月作為RFC3711發佈,提供加密、消息認證、完整性保證和重放保護。

RTSP(Realtime Streaming Protocol)

  • 于1998年发布为RFC 2326。RTSP 2.0 于2016年发布为RFC 7826,作为RTSP 1.0的替代品。
  • 专为娱乐和通信系统的使用,以控制流媒体服务器。
    • 媒体服务器的客户端发布VCR命令,例如播放,录制和暂停,以便于实时控制从服务器到客户端(视频点播)或从客户端到服务器(语音录音)的媒体流。
  • 流数据本身的传输不是RTSP的任务。大多数RTSP服务器使用实时传输协议(RTP)和实时传输控制协议(RTCP)结合媒体流传输。
  • 与RTP最大的区别在于:
    • RTSP是一种双向实时数据传输协议,它允许客户端向服务器端发送请求,如回放、快进、倒退等操作
    • 当然RTSP可基于RTP来传送数据,还可以选择TCP、UDP、组播UDP等通道来发送数据,具有很好的扩展性。
    • 它是一种类似于HTTP协议的网络应用协议。

RTMP(Real Time Messaging Protocol)

  • Adobe于2012年12月21日发布了该协议1.0版本的规范。
  • 是 Adobe Systems 公司为 Flash 播放器和服务器之间音频、视频和数据传输开发的开放协议。
  • 协议基于 TCP,是一个协议族,包括 RTMP 基本协议及 RTMPT/RTMPS/RTMPE 等多种变种。
    • RTMPT封装在HTTP请求之中,可穿越防火墙;
    • RTMPS类似RTMPT,但使用的是HTTPS连接。
    • RTMPE,使用Adobe自有安全機制加密的RTMP。雖然實現上的細節是專有的,但該機制使用行業標準的密碼學加密演算法。
  • RTMP 是目前主流的流媒体传输协议,广泛用于直播领域。
  • 默认通信端口1935。RTMP URL格式:rtmp://ip:[port]/appName/streamName
  • 特点
    • RTMP协议是采用实时的流式传输,所以不会缓存文件到客户端,这种特性说明用户想下载RTMP协议下的视频是比较难的;
    • 视频流可以随便拖动,既可以从任意时间点向服务器发送请求进行播放,并不需要视频有关键帧。相比而言,HTTP协议下视频需要有关键帧才可以随意拖动。
    • RTMP协议支持点播/回放(通俗点将就是支持把flv,f4v,mp4文件放在RTMP服务器,客户端可以直接播放),直播(边录制视频边播放)。

MMS(Microsoft Media Server Protocol)

  • 访问并流式接收Window Media服务器中.asf文件的一种协议。
  • 可以用Windows自带的Windows Media Player来观看

Web RTC(Web Real-Time Communications)

  • 于2011年6月1日开源并在Google、Mozilla、Opera支持下被纳入万维网联盟的W3C推荐标准。
  • 是一个支持网页浏览器进行实时语音对话或视频对话的API。
  • 目前主要应用于视频会议和连麦中。

HLS(Http Live Streaming, 明显是基于HTTP)

  • 是由苹果提出基于HTTP的流媒体传输协议。
  • 原理
    • 直播客户端获取到的并不是一个完整的数据流,HLS协议在服务器端将直播数据流存储为连续的、很短时长的媒体文件(MPEG-TS格式)(MPEG-2 Transport Stream;又称MPEG-TS、MTS、TS),而客户端则不断的下载并播放这些小文件,因为服务器总是会将最新的直播数据生成新的小文件,这样客户端只要不停的按顺序播放从服务器获取到的文件,就实现了直播。
  • 特点
    • 优点就是HTML5可以直接打开播放;分段文件的时长很短,客户端可以很快的选择和切换码率,以适应不同带宽条件下的播放。
    • 缺点就是延迟高。

HTTP-FLV(明显是基于HTTP)

  • 将直播流模拟成FLV文件,通过HTTP协议进行下载的模式来实现流媒体传输的协议。

各种软件使用的流式协议

moonlight

官网写着

Moonlight (formerly Limelight) is an open source implementation of NVIDIA’s GameStream protocol.

那么 NVIDIA’s GameStream protocol是什么呢?

NVIDIA uses high speed, low latency video encoders built into GeForce GTX or RTX GPUs along with an efficient streaming software protocol integrated into GeForce Experience.

我只能说看上去像自研的~但是马上也要没了

Nvidia isn’t just ending support for GameStream, it’s planning to fully remove the feature from existing Shield hardware in February 2023.
Nvidia is recommending that Shield users switch to Steam Link, which is a similar way of streaming PC games to a Shield device.

github老哥分析了。但我只能说肯定不是上面常见的类型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
sequenceDiagram
Client ->> Host: Discovery/Connect
Note over Client: Send client connection ID
Host ->> Client: Discovery/Connect ACK
Note over Client: Got host connection ID, start client handshake
Client ->> Host: Reliable/Control:ClientHandshake
par Discovery Channel
loop While True
Host ->> Client: Unconnected/Discovery:PingRequest
Client ->> Host: Unconnected/Discovery:PingResponse
end
end
Host ->> Client: Reliable/Control:ServerHandshake
Note over Client: Got mtu, start authentication
Client ->> Host: Reliable/Control:AuthenticationRequest
Host ->> Client: Reliable/Control:AuthenticationResponse
Host ->> Client: Reliable/Control:NegotiationInit
Note over Client: Got host supported audio/video codecs
Client ->> Host: Reliable/Control:NegotiationSetConfig
Note over Client: Send selected codecs and config
Host ->> Client: Reliable/Control:NegotiationSetConfig
Note over Client: Got final config, respond with complete
Client ->> Host: Reliable/Control:NegotiationComplete
par Audio Data Channel
Host ->> Client: Reliable/Control:StartAudioData
loop Not StopAudioData
Host ->> Client: Unreliable/Data:Packet
end
and Video Data Channel
Host ->> Client: Reliable/Control:StartVideoData
loop Not StopVideoData
Host ->> Client: Unreliable/Data:Packet
end
end
Client ->> Host: Discovery/Disconnect

流式传输 视频压缩编码

主流还是 H.264 或者 HEVC。 流式传输时为了保证帧率可能会牺牲画面。

Steam Link 的相关设置

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

山东布谷科技 https://www.bilibili.com/read/cv9502267?from=search&spm_id_from=333.337.0.0 出处:bilibili

Wake On Lan(Wol)

简介

Wake-on-LAN 也叫 WoL,指通过网络消息打开或唤醒计算机。

WoL 需要由另一台「同局域网」设备发送网络信号,任意有能力发送 WoL 信号 的设备都可以充当此角色;在远程办公场景中,则最好由「带有线网卡的低功耗设备」来执行,这类设备包括但不限于以下选项:

  1. 带网络唤醒 WoL 功能的路由器产品
  2. OpenWrt Linux 设备「TP-Link 703n」
  3. 树莓派「推荐 2 代」

网络扫描

获取局域网下设备MAC地址, 或者OpenWRT直接显示

平台 工具
Windows Softperfect Network Scanner
Linux arp-scan
Android / iOS Fing / PingTools

发出唤醒信息的软件

可以使用的幻数据包唤醒工具有:

平台 工具 特点
Windows wolcmd.exe 命令行,跨网段
Linux/MacOS etherwake, wakeonlan 命令行,同网段
Android / iOS Fing / PingTools 可扫描

请注意,WoL 属于无状态协议,仅发送、不确认。

问题:抓包发现 WolCmd和wakeonlan的目的地址不同

1
2
3
4
5
6
7
8
9
10
11
WolCmd.exe 90:09:D0:15:70:B8 192.168.233.242 255.255.255.255 9 (目的地址 192.168.233.242)
WolCmd.exe 90:09:D0:15:70:B8 192.168.233.242 255.255.255.0 9 (测试过本地能成功,br-lan路由器能抓, 本地wireshark目的地址 192.168.233.255)


WolCmd.exe 90:09:D0:15:70:B8 192.168.233.242 0.0.0.0 9 (目的地址 192.168.233.109.53362 > 255.255.255.255.9 注意:109是macboook)

shaojiemike@shaojieikedeAir ~/github/hugoMinos (main*) [11:46:22]
> wakeonlan 90:09:D0:15:70:B8 (目的地址 192.168.233.109.53362 > 255.255.255.255.9 注意:109是macboook)
Sending magic packet to 255.255.255.255:9 with payload 90:09:D0:15:70:B8
Hardware addresses: <total=1, valid=1, invalid=0>
Magic packets: <sent=1>

路由遇到目的MAC是广播地址怎么办?

IP的广播有三种:

  1. 255.255.255.255叫本地广播,也叫直播,direct broadcast,不跨路由器。
  2. 172.16.33.255叫子网广播,广播给172.16.33.0这个子网,可以跨路由器
  3. 172.16.255.255叫全子网广播,广播给172.16.0.0这个主网,可以跨路由器。

路由器是三层设备,可以隔离广播,但并不是所有广播都隔离。事实上只有本地广播路由器才不转发,对于子网广播和全子网广播,路由器是转发的。

为什么呢?我们来看255.255.255.255的广播,在MAC的封装中,对应的目的MAC是广播,而子网广播和全子网广播,对应的目的MAC是单播,所以路由器会转发。所以路由器隔离的广播是目的MAC为全1的广播,对于目的MAC是单播的上层广播,路由器是不能隔离的。

广播规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
> netstat -r -anv
Routing tables

Internet:
Destination Gateway Flags Netif Expire
default 192.168.233.1 UGScg en0
127.0.0.1 127.0.0.1 UH lo0
192.168.233 link#11 UCS en0 !
192.168.233.1/32 link#11 UCS en0 !
192.168.233.1 5c:2:14:b3:2:a UHLWIir en0 1172
192.168.233.109/32 link#11 UCS en0 !
192.168.233.242 90:9:d0:15:70:b8 UHLWI en0 151
192.168.233.255 ff:ff:ff:ff:ff:ff UHLWbI en0 !
255.255.255.255/32 link#11 UCS en0 !
255.255.255.255 ff:ff:ff:ff:ff:ff UHLWbI en0 !

路由器

1
2
3
4
5
6
7
8
9
[root@ax6s ~]$ ip route get to 192.168.233.242 from 192.168.233.142 iif lan2
192.168.233.242 from 192.168.233.142 dev br-lan
cache iif lan2
[root@ax6s ~]$ ip route get to 192.168.233.255 from 192.168.233.142 iif lan2
broadcast 192.168.233.255 from 192.168.233.142 dev lo table local
cache <local,brd> iif lan2
[root@ax6s ~]$ ip route get to 255.255.255.255 from 192.168.233.142 iif lan2
broadcast 255.255.255.255 from 192.168.233.142 dev lo
cache <local,brd> iif lan2

电脑需要远程被远程唤醒

电脑设置

  1. 「网络连接」
    1. 以太网(有线网)属性
    2. 【网络】(Realtek PCIe 2.5GbE Family Controller)下配置
    3. 【电源管理】勾选「允许此设备唤醒计算机」以及「只允许幻数据包唤醒计算机」
  2. BIOS打开相关选项
    1
    2
    3
    4
    5
    Automatic Power On
    Wake on LAN/WLAN
    Power Management
    Power On by Onboard LAN
    Power On by PCI-E Devices

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

Nas 太吵,需要自动关机

参考文献

https://sspai.com/post/67003

https://www.depicus.com/wake-on-lan/wake-on-lan-cmd

Ed2k

基本原理

区别于BT,核心概念在于文件共享。

  1. 设置共享目录,该目录中的所有文件,都会实时共享到eDonkey和KAD网络中。
  2. 目录中共享了的文件都会生成eD2k链接,所有人通过相应的eD2k链接,都能够拿到你共享的文件,
    1. 一旦有人下载相应文件,那么你的eMule客户端就会上传数据。
    2. 平时使用eD2k链接下载,资源也是来自他人eMule所共享的文件的。
    3. 当然,共享目录中也可以啥都不放,但很多eMule客户端都拥有队列优先级机制,上传得少,下载速度也会被限制。

与BT的区别

  1. 资源持久性
    1. 对于BT来说,用户被视为下载者。当用户上传到指定比率作为一个下载者的义务就完成了,一般就停止上传了,这使得BT在下热门资源的时候速度快,但是对冷门资源来说即使这个文件没有被删除也不会有上传者了。
    2. 而对于eMule来说,用户被视为分享者。只要用户文件没被删除作为资源分享者就一直上传,这样可以长期保源。
  2. 资源搜索能力
    1. BT协议中没搜索功能
    2. eMule搜索的时候每个资源大小来源数甚至拥有者对其的评价都是一目了然的,这样使得资源广泛分布,也有利于资源优胜劣汰,从而达到长期保源的目的。

基本概念

eD2k:

eDonkey网络所使用的协议,eDonkey网络所共享的文件会生成eD2k开头的链接。

电驴

eDonkey2000:(又称:eDonkey;缩写:eD2k;非官方中文译名:电驴)最先开发使用eDonkey网络的文件共享客户端软件。2000年起开发,2005年停止维护,之后eDonkey网络被其他软件沿用。

电骡

eMule:(官方中文名:电骡)eMule及其Mods是现在最流行的一款eDonkey网络文件共享客户端软件。2002年起开发。

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

作者:qysnn
链接:https://www.zhihu.com/question/19922200/answer/29022933
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Php

enable php curl extension

需要进一步的研究学习

暂无

遇到的问题

暂无

开题缘由、总结、反思、吐槽~~

参考文献

Bash Scripting

简介

记录一下bash脚本编写的东东,可以参考cheatsheet

调试打印

在Bash脚本里打开打印,并利用shellprof./shellprof ./testcase.sh计算时间。

1
2
3
4
5
6
7
8
9
#!/bin/bash

# 使用 trap 来捕获 DEBUG 信号,每次执行命令前触发
trap 'echo "$BASH_COMMAND"' DEBUG

# 设置调试模式打印前缀PS4,包含时间戳和行号
export PS4='+ $(date "+%Y-%m-%d %H:%M:%S.%3N")\011 '

set -x # 开启调试模式

基础知识

参数

  • $? 是上一个指令执行的状态值
  • $@ 代表shell脚本的命令行参数. $1 , $2 , etc., 分别代表命令行传入的第一个和第二个参数。举例,对于命令./run.sh XXX YYY,$1代表XXX , $2代表YYY

#匹配并删除最短前缀

1
2
3
4
5
6
7
8
9
10
str="/path/to/foo.cpp"
echo "${str%.cpp}" # /path/to/foo
echo "${str%.cpp}.o" # /path/to/foo.o
echo "${str%/*}" # /path/to

echo "${str##*.}" # cpp (extension)
echo "${str##*/}" # foo.cpp (basepath)

echo "${str#*/}" # path/to/foo.cpp
echo "${str##*/}" # foo.cpp

在 Bash 脚本中,### 符号用于字符串操作,具体用于删除前缀部分:

  1. ${str#pattern}:删除变量 str 中最短匹配 pattern 的前缀。
  2. ${str##pattern}:删除变量 str 中最长匹配 pattern 的前缀。

例如:

  1. echo "${str##*.}":这行代码使用 ## 删除了最后一个 . 及其前面的所有内容,从而只保留了文件扩展名 cpp。这是因为 * 匹配所有字符。
  2. echo "${str##*/}":这行代码使用 ## 删除了最后一个 / 及其前面的所有内容,因此只保留了文件名 foo.cpp
  3. ${str#*/} 删除了第一个 / 之前的部分,结果是 path/to/foo.cpp
  4. ${str##*/} 删除了最后一个 / 之前的所有部分,结果是 foo.cpp

这两个符号用于简化路径处理和提取文件名等。

变量作用域

  • Bash 中的变量是 全局变量,也就是说,在脚本中的任何地方都可以访问到这个变量,除非使用 local 关键字将其作用域限制在特定的函数中。
  • local 声明的变量确实限制了它的作用域,但作用域仅限制在当前函数及其子函数(嵌套函数)内。对于嵌套函数,还是共用(读取和修改)上层的local变量。

函数传参

  • Bash里的函数传参和脚本的命令行参数也是共用$@$1等,但是默认是函数的局部变量。
  • 如果忘记使用局部变量,这常会导致一个问题:
    • 外层的for循环的i被内层函数的for循环i修改导致循环异常。
    • 解决方案:需要将内层函数的for循环i定义为local,来与上层的隔离。

其他

  • /dev/null是一个几乎不管向它写入什么,都只返回成功,但是什么都没真的写入的文件。换句话说就是个“无底洞”,扔进去的东西肯定算扔进去了,但是扔进去就看不见了。

Environment

1
2
3
4
5
6
7
8
9
10
11
# read
SCRIPT_DIR="$(dirname $0)"

# set
export HOSTNAME="$(hostname)"

# check Environment
if [[ -z "${ITHEMAL_HOME}" ]]; then
echo "ITHEMAL_HOME environment variable must be set!"
exit 1
fi

实例

判断docker是否启动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function container_id() {
sudo docker ps -q --filter 'name=ithemal$'
}

CONTAINER="$(container_id)"

if [[ -z "${CONTAINER}" ]]; then
read -p "Container is not currently running. Would you like to start it? (y/n) " -r

if [[ !($REPLY =~ ^[Yy]) ]]; then
echo "Not starting."
exit 1
fi

# others
fi

尝试获取sudo权限

1
2
3
4
5
6
function get_sudo() {
if ! sudo -S true < /dev/null 2> /dev/null; then
echo "sudo access required for docker:"
sudo true
fi
}

重连或者创建一个到名称为$1tmux窗口

1
2
3
4
5
6
7
8
9
#!/usr/bin/env bash

SESSION=$(tmux ls -F '#S #{session_attached}' | grep ' 0$' | head -n 1 | awk '{$NF=""; print $0}' | awk '{$1=$1;print}')

if [ ! -z "${SESSION}" ]; then
tmux attach -t "${SESSION}"
else
tmux new "bash -l"
fi

参考文献