FFMPEG下载M3U8为MP4格式
ffmpeg -i https://xxx.m3u8 -c copy xxx.mp4
ffmpeg -i https://xxx.m3u8 -c copy xxx.mp4
网上找了很多资料都不对。无奈自己分析。
m3u8本质上是一个列表,动态输出的。大概格式如下:
curl http://121.19.134.82:808/tsfile/live/1030_1.m3u8
#EXTM3U
##EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:15952719
#EXTINF:5, no desc
live_1030_1_15952715.ts?key=txiptv&key2=15952715
#EXTINF:5, no desc
live_1030_1_15952716.ts?key=txiptv&key2=15952716
#EXTINF:5, no desc
live_1030_1_15952717.ts?key=txiptv&key2=15952717
#EXTINF:5, no desc
live_1030_1_15952718.ts?key=txiptv&key2=15952718
#EXTINF:5, no desc
live_1030_1_15952719.ts?key=txiptv&key2=15952719
可以看到这里面,是没有任何信息的。
于是我把ts文件下载回来,这就是一个小的视频片段。
vlc打开,是有标题信息的,所以,其实是藏在这个ts文件里面了。
010editor打开这个文件,搜索ASCII码,比如我搜“CCTV”。
发现都是藏在一堆的0xFF前面。于是找规律,写代码,做测试。
最终成品如下:
import binascii
import sys
import re
def find_all_contiguous_ff(file_path, target_length=144, preceding_bytes=20):
with open(file_path, 'rb') as file:
data = file.read()
# 十六进制的 FF 字符串
target_hex = b'\xFF' * target_length
# 查找所有连续的 FF
start_index = 0
results = []
while True:
index = data.find(target_hex, start_index)
if index == -1:
break
# 提取前面的 20 个字节
preceding_start_index = max(0, index - preceding_bytes)
preceding_data = data[preceding_start_index:index]
# 转换为十六进制字符串
preceding_hex_string = binascii.hexlify(preceding_data).decode('ascii')
# 使用 binascii.unhexlify 转换为字节串
preceding_bytes_data = binascii.unhexlify(preceding_hex_string)
results.append(preceding_bytes_data)
# 更新起始索引,继续查找下一个
start_index = index + target_length
if results:
for idx, result in enumerate(results):
ss = binascii.hexlify(result).decode("ascii")
if str(ss[:2])=="01":
return get_relevant_string(ss)
else:
print("没有找到连续的 144 个 FF")
def extract_ascii_from_hex(hex_string):
# 将十六进制字符串转换为字节串
byte_data = binascii.unhexlify(hex_string)
trimmed_byte_data = byte_data[:-4]
# 尝试将字节串解码为 ASCII 字符串
try:
decoded_string = trimmed_byte_data.decode('ascii', errors='ignore')
except UnicodeDecodeError:
return None
# 查找所有可能的 ASCII 字符串(假设 ASCII 字符串是由可打印字符组成的)
# 这里只是一个示例,实际应用中你可能需要根据实际情况调整正则表达式
ascii_strings = re.findall(r'[ -~]+', decoded_string)
return ascii_strings
def get_relevant_string(hex_string):
# 提取 ASCII 字符串
ascii_strings = extract_ascii_from_hex(hex_string)
# 根据提取的字符串数量返回相应的字符串
if len(ascii_strings) > 1:
return ascii_strings[1]
elif len(ascii_strings) == 1:
return ascii_strings[0]
else:
return "没有找到有效的字符串"
# 使用示例
file_path = sys.argv[1]
find_all_contiguous_ff(file_path)
使用效果:
Python2
此文为获取Maya2018在注册表中的路径
import _winreg
string = r'SOFTWARE\Autodesk\Maya\2018\Setup\InstallPath'
handle = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, string)
location, _type = _winreg.QueryValueEx(handle, "MAYA_INSTALL_LOCATION")
print(location)
Python3
import winreg
string = r'SOFTWAREAutodeskMaya2018SetupInstallPath'
handle = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, string, 0, (winreg.KEY_WOW64_64KEY + winreg.KEY_READ))
location, _type = winreg.QueryValueEx(handle, "MAYA_INSTALL_LOCATION")
print(location)
https://www.ip.cn/api/index?ip=221.213.24.219&type=1
{"rs":1,"code":0,"address":"中国 云南省 昆明市 联通","ip":"221.213.24.219","isDomain":0}
https://opendata.baidu.com/api.php?query=221.213.24.219&co=&resource_id=6006&oe=utf8
{"status":"0","t":"","set_cache_time":"","data":[{"ExtendedLocation":"","OriginQuery":"221.213.24.219","SchemaVer":"","appinfo":"","disp_type":0,"fetchkey":"221.213.24.219","location":"云南省昆明市 联通","origip":"221.213.24.219","origipquery":"221.213.24.219","resourceid":"6006","role_id":0,"schemaID":"","shareImage":1,"showLikeShare":1,"showlamp":"1","strategyData":{},"titlecont":"IP地址查询","tplt":"ip"}]}
https://searchplugin.csdn.net/api/v1/ip/get?ip=221.213.24.219
{"code":200,"msg":"success","data":{"address":"中国 云南 昆明 联通","ip":"221.213.24.219"}}
https://ip.useragentinfo.com/jsonp?ip=221.213.24.219
callback({"country": "中国", "short_name": "CN", "province": "云南省", "city": "昆明市", "area": "", "isp": "联通", "net": "城域网", "ip": "221.213.24.219", "code": 200, "desc": "success"});
https://webapi-pc.meitu.com/common/ip_location?ip=121.8.215.106
{"reqid":"8014a00789e5450dc8f4b631817ee2e0","code":0,"data":{"121.8.215.106":{"area_code":"86","city":"广州市","city_id":160063402,"continent":"亚洲","continent_code":"AP","country_id":100000,"isp":"电信","latitude":23.3283,"longitude":113.75837,"nation":"中国","nation_code":"CN","province":"广东","province_id":440000,"subdivision_1_iso_code":"*","subdivision_1_name":"广东","subdivision_2_iso_code":"*","subdivision_2_name":"广州市","time_zone":"UTC+8"}}}
U-NAS系统自带的MYSQL。
用mysql连接上,执行show tables,是能看到user表的。
但是更新密码,就报错。
ERROR 1356 (HY000): View 'mysql.user' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
1. 检查 mysql.user 是否是视图
首先,检查 mysql.user 是否是视图。你可以使用以下命令:
SHOW FULL TABLES IN mysql WHERE TABLE_TYPE = 'VIEW';
2. 查看视图定义
如果 mysql.user 是视图,可以通过以下命令查看视图的定义:
SHOW CREATE VIEW mysql.user;
3. 检查权限
确保你有足够的权限来更新 mysql.user 表。你可以查看当前用户的权限:
SHOW GRANTS FOR CURRENT_USER();
返回如下信息:
MariaDB [mysql]> SHOW CREATE VIEW mysql.user\G;
*************************** 1. row ***************************
View: user
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=mariadb.sys@localhost SQL SECURITY DEFINER VIEW user AS select global_priv.Host AS Host,global_priv.User AS User,if(json_value(global_priv.Priv,'$.plugin') in ('mysql_native_password','mysql_old_password'),ifnull(json_value(global_priv.Priv,'$.authentication_string'),''),'') AS Password,if(json_value(global_priv.Priv,'$.access') & 1,'Y','N') AS Select_priv,if(json_value(global_priv.Priv,'$.access') & 2,'Y','N') AS Insert_priv,if(json_value(global_priv.Priv,'$.access') & .........省略
从视图定义中可以看出,mysql.user 视图基于 global_priv
表并从其中提取数据。因此,要更新 mysql.user 视图中的数据,需要直接更新 global_priv
表。
更新 global_priv 表
根据 mysql.user 视图的定义,authentication_string 存储在 global_priv 表的 Priv 列的 JSON 字段中。你需要使用 JSON 操作来更新它。
USE mysql;
-- 更新密码和插件
UPDATE global_priv
SET Priv = JSON_SET(Priv, '$.authentication_string', '*E9999.......................EEEEE', '$.plugin', 'mysql_native_password')
WHERE User='root' AND Host='localhost';
-- 刷新权限
FLUSH PRIVILEGES;
-- 检查更新是否成功
SELECT User, Host, JSON_UNQUOTE(JSON_EXTRACT(Priv, '$.authentication_string')) AS authentication_string, JSON_UNQUOTE(JSON_EXTRACT(Priv, '$.plugin')) AS plugin
FROM global_priv
WHERE User='root' AND Host='localhost';