2019年10月

这个接口的好处是不需要cookies,也不需要计算某个参数,替换tvid就可以用。
至于headers中的sign参数,通常情况下和t一起出现,有效期很长,另外目前不需要sign和t也能请求。
代码示例如下

import requests

url = "http://iface2.iqiyi.com/video/3.0/v_download"

querystring = {"api":"nil","app_t":"1","app_p":"gphone","app_k":"69842642483add0a63503306d63f0443","app_v":"10.9.0","dev_ua":"Redmi","dev_os":"10","dev_hw":"null","album_id":"239229801","tv_id":"8502453100","platform_id":"10","play_core":"nil","net_sts":"16","usr_res":"512","secure_v":"1","secure_p":"GPhone","qdv":"1","api_v":"9.8","req_sn":"1571529770886"}

headers = {
    'sign': "abf536b8e1203ae3f2e6c5c8dbb9b65d",
    'User-Agent': "iqiyi/com.qiyi.video/10.9.0/NetLib-okhttp/3.12.5.1",
    't': "529636367",
    'Accept': "*/*",
    'Host': "iface2.iqiyi.com",
    'Accept-Encoding': "gzip, deflate"
    }

response = requests.request("GET", url, headers=headers, params=querystring)

print(response.text)

返回示例

{
    "code": 0,
    "album": {
        "_blk": 0,
        "_cid": 2,
        "_ct": "2019-03-18 10:34:23",
        "_id": 239229801,
        "_img": "http://m.iqiyipic.com/image/20191010/5f/ad/a_100272782_m_601_m2_120_160.jpg",
        "_pc": 2,
        "_pid": 239229801,
        "_t": "光荣时代",
        "_tvct": 1,
        "_tvs": 46,
        "ctype": 0,
        "fst_time": "2019-04-25",
        "tv_id": 8502453100,
        "cpt_l": 1,
        "cpt_r": 2,
        "t_pc": 1,
        "_dn": "2736",
        "h1_img": "http://m.iqiyipic.com/image/20191010/5f/ad/a_100272782_m_601_m2_180_236.jpg",
        "boss_type": 99,
        "clm": "",
        "tvfcs": "张译黄志忠明暗对决",
        "year": "2019",
        "t": "光荣时代",
        "v2_img": "http://m.iqiyipic.com/image/20191010/5f/ad/a_100272782_m_601_m2_284_160.jpg",
        "logo": 1,
        "logo_position": -1,
        "logo_hidden": [],
        "business_type": []
    },
    "video": {
        "_id": 8502453100,
        "_n": "光荣时代第13集",
        "subtitle": "朝阳冒充中统",
        "_od": 13,
        "desc": "北平开始打击“粮老虎”,很多奸商被抓。郑朝阳从奸商的往来账目中发现了杨凤刚的驻地——平西沙子口旧矿场。郑朝阳化妆粮食商人一路做了记号到旧矿场见到杨凤刚,杨凤刚知道郑朝阳是警察。郑朝阳则冒充自己是中统骗过杨凤刚,但还是被关押起来。在关押处发现了冼怡竟然也关在这里。矿场外,包围圈完成。矿场里,杨凤刚获悉郑朝阳说谎。下令连冼怡一起处决。这时,冼登奎带着委任状来和杨凤刚谈判。城里,郑朝山从旧警察多门的口中探听到郑朝阳带人抓捕杨凤刚的情报,紧急给杨凤刚发报撤离。\n",
        "_img": "http://m.iqiyipic.com/image/20191014/77/39/v_139408871_m_601_160_90.jpg",
        "_dn": "2705",
        "s_t": 90,
        "e_t": 2530,
        "ts_res": {
            "16": {
                "vid": "becedab20c5e7a6f4a436d039cd0b103",
                "len": 368685759,
                "f4v_url": "",
                "m3u8_url": "",
                "dolby_len": 0,
                "h265_len": 0,
                "audio_aac_len": 0
            },
            "512": {
                "vid": "a509b538d47e0e59c0ac51c16863950e",
                "len": 704308245,
                "f4v_url": "",
                "m3u8_url": "",
                "dolby_len": 0,
                "h265_len": 0,
                "audio_aac_len": 0
            },
            "4": {
                "vid": "bc4a5528adf8ead809255ff2b5b183ea",
                "len": 121820901,
                "f4v_url": "",
                "m3u8_url": "",
                "dolby_len": 0,
                "h265_len": 0,
                "audio_aac_len": 0
            },
            "8": {
                "vid": "e633dfc4ecb17a5824a86c728ca2ed4e",
                "len": 163529602,
                "f4v_url": "",
                "m3u8_url": "",
                "dolby_len": 0,
                "h265_len": 0,
                "audio_aac_len": 0
            },
            "128": {
                "vid": "79fb300726b67a3d0dcdc0afd81d45b3",
                "len": 65016514,
                "f4v_url": "",
                "m3u8_url": "",
                "dolby_len": 0,
                "h265_len": 0,
                "audio_aac_len": 0
            }
        },
        "mp4_res": {
            "1": {
                "vid": "716a30d6ec16b88b819f991d5a83857f",
                "url": "",
                "len": 77340238
            },
            "32": {
                "vid": "ff9417948c6a9d9f96e7c8778228c27d",
                "url": "",
                "len": 128380783
            },
            "2": {
                "vid": "ff9417948c6a9d9f96e7c8778228c27d",
                "url": "",
                "len": 128380783
            }
        },
        "video_ctype": 0,
        "boss_type": 1,
        "pre_img": {
            "pre_img_url": "http://preimage2.iqiyipic.com/preimage/20191018/87/fe/v_139408871_m_612_m1_220_124.jpg",
            "rule": "1-30",
            "interval": 10
        },
        "ta": {
            "215235805": {
                "id": 215235805,
                "img": "http://pic2.iqiyipic.com/image/20191010/66/09/p_2001251_m_601_m3_128_128.jpg",
                "name": "黄志忠"
            },
            "204240905": {
                "id": 204240905,
                "img": "http://pic6.iqiyipic.com/image/20181229/94/97/p_1037073_m_601_m2_128_128.jpg",
                "name": "李添诺"
            },
            "203609805": {
                "id": 203609805,
                "img": "http://pic6.iqiyipic.com/image/20181229/08/12/p_1030762_m_601_m4_128_128.jpg",
                "name": "张译"
            },
            "234334505": {
                "id": 234334505,
                "img": "http://pic3.iqiyipic.com/image/20181228/ed/19/p_5232901_m_601_m2_128_128.jpg",
                "name": "张隽溢"
            },
            "215381805": {
                "id": 215381805,
                "img": "http://pic1.iqiyipic.com/image/20181229/ed/0d/p_2013408_m_601_m3_128_128.jpg",
                "name": "潘之琳"
            },
            "214463605": {
                "id": 214463605,
                "img": "http://pic7.iqiyipic.com/image/20181228/08/81/p_2008149_m_601_m6_128_128.jpg",
                "name": "黄品沅"
            },
            "214432805": {
                "id": 214432805,
                "img": "http://pic4.iqiyipic.com/image/20181229/da/a2/p_2006722_m_601_m3_128_128.jpg",
                "name": "王骁"
            }
        },
        "vip_type": "0",
        "pay_mark": 2,
        "business_type": [],
        "play_mode": 1,
        "fst_time": "20191019",
        "video_tail_start_point": 2530000,
        "bullet_num": "300"
    },
    "setting": {
        "dl_type": 4,
        "ts": "16,4,512,8,128",
        "authResult": {
            "auth_success": false
        }
    }
}

通过p值/pck/P00001直接登陆(未失效时)

https://passport.iqiyi.com/apis/reglogin/generate_tauthcookie.action?agenttype=30&authcookie={p值}&ptid=01012001020000000000&cb_url=http://www.iqiyi.com

返回ip等位置有关信息

http://ip.geo.iqiyi.com/cityjson?format=json
http://ip.geo.iqiyi.com/queryZone?format=json

返回流行的热门关键词?

https://xinqi.if.iqiyi.com/r/mixer/public/keyword/json?src=606b62b5b934470485fb8053e6705521

关键词搜索,返回单一结果

http://xinqi.if.iqiyi.com/fenghuolun/v2?name=%E7%A0%B4%E5%86%B0%E8%A1%8C%E5%8A%A8

当前时间戳

https://time.iqiyi.com/

电影随机推荐

https://qiyu.iqiyi.com/portal/p13n?cid_num=-4_2&area=c_frog&rltfmt=json&ppuid=

登录token(?)

https://passport.iqiyi.com/apis/qrcode/gen_login_token.action?ptid=01012001020000000000&device_name=xiaomi

热搜词

https://xinqi.if.iqiyi.com/search/hotwords?channel=2

上传接口,不知道咋用的

https://upload.iqiyi.com/yunpan_file_upload

点播状态检查接口

https://serv.vip.iqiyi.com/pay/buyWeb.action?layCode=992127a1bb87988d&aid=1566844700

不知道是啥接口

https://uaa.if.iqiyi.com/who?p=pc_client&id=

tvid得到视频页面地址,注意channel,实际打开是二维码图像

http://player.share.qiyi.com/redirector/f/s/pps.html?channel=3&platform=1&pic=undefined&tvName=undefined&tvId=2256822000

tvid得到链接分享接口

http://vodguide.ppstream.iqiyi.com/share_b.html?tvid=226128201

搜索推荐

http://search.video.qiyi.com/m?if=defaultQuery&platform=17&is_qipu_platform=1

根据tvid得到详细结果

http://mixer.video.iqiyi.com/mixin/videos/7995486500?src=e9194cb155e14ceba4d63c185289b3c5

按aid+关键词返回一些有关的内容,末尾参数m可选news、voice等,留空会返回详细(全部相关视频),uid可有可无

https://qiquan.if.iqiyi.com/video/v2?id=220109214&js_ver=7.0.41.3499&client_ver=7.0.96.7232&wn_ver=7.0.41.3499&uid=&client_mode=youth&brightness=light&theme=default&mkt=zh-Hans&key=全职高手之巅峰荣耀&page=0&size=20&m=voice

根据aid返回相关内容,和上面的基本一致,只是api不太一样

https://qiquancdn.if.iqiyi.com/video/v2?id=220109214&js_ver=7.0.41.3499&client_ver=7.0.96.7232&wn_ver=7.0.41.3499&uid=&client_mode=youth&brightness=light&theme=default&mkt=zh-Hans

获取一些接口的ip配置,POST方法,返回参考这里

链接 ->
http://puma-api.iqiyi.com/tiger/fetch HTTP/1.1
请求头 -> 
qyid: macid(32位,实际上可以随机)
User-Agent: QYPlayer/Windows/4.5.10;BT/mcto;NetType/unknown;Hv/;QTP/1.0.15.5
Content-Type: application/x-www-form-urlencoded
请求体 ->
key={"PLT":2,"PLT_CODE":"01012001010000000000","PLT_KRUS":"pc_win32_player","CORE_VER":40510,"OS":"windows","OS_VER":6002,"DEVICE_ID":"macid","CPU_COUNT":88,"CPU_GHZ":280,"CPU_INFO":"Intel(R) Core(TM) i9-9900K CPU @ 3.80GHz","CPU_MODEL":"","AVC_CODEC_PROFILE":-1,"AVC_CODEC_LEVEL":-1,"HVC_CODEC_PROFILE":-1,"HVC_CODEC_LEVEL":-1}

相关搜索

http://search.video.iqiyi.com/m?if=related_query&key=全职高手之巅峰荣耀&js_ver=7.0.41.3499&client_ver=7.0.96.7232&wn_ver=7.0.41.3499&uid=1199057052&client_mode=youth&brightness=light&theme=default&mkt=zh-Hans

tvid+vid获取详细信息,vid可以没有,这时改为nil即可

http://cache.video.qiyi.com/vi/8614163300/nil/

一些参数对照关系

http://list3.ppstream.com.iqiyi.com/cfg2/global.json

获取合集全部分集的vid信息,要sign

https://pcaapi.iqiyi.com/download_info/236681601?return_format=pb&src=&sign=43F30BFA22BDDC9A829FB13265B8D803

<center><font size=7 color=#50616d>typecho文本居中和字体大小</font></center>

居中用<center>标签
字体大小颜色控制用<font>标签
字体大小最大是7,再大也不会更大了

6 typecho文本居中和字体大小

7 typecho文本居中和字体大小

获取截图

首先了解如何通过ffmpeg对视频进行截图,这里介绍两种方式,通过时间和通过帧数

  • 对指定帧截图,下面这个命令是获取input.mp4第666帧的图像
ffmpeg -i input.mp4 -vf "select=gte(n\,666)" -vframes 1 output.jpg -y
  • 对指定时间截图,下面这个命令是获取input.mp4第47.50秒的图像
ffmpeg -ss 47.50 -i input.mp4 -vframes 1 output.jpg -y

output.jpg
Tips!

  1. -y的作用是,如果已经存在output.jpg,那么执行命令不会提示文件已经存在而是直接覆盖
  2. -ss放在-i选项前面
  3. -ss形式有两种,一种是示例中那样,代表秒数且可以有小数位;另一种的形式是00:02:44.432。两种方式都支持反向索引,加个负号即可

图像缩放

既然要自定义,那么截图的图像分辨率大小自然也应当支持指定,通常用scale滤镜来做
如果想同时使用多个滤镜,那么用逗号分隔开来即可,示例如下。

  • 获取input.mp4第666帧图像,并缩放为短边为2160像素的尺寸
ffmpeg -i input.mp4 -vf "select=gte(n\,666),scale=-1:2160" -vframes 1 output.jpg -y

Tips!

  1. 通常为了简便,使用scale滤镜时指定短边的尺寸即可,但是对于某些像素比不是1:1的视频(比如一些日剧),建议明确指定长边尺寸,比如scale=3840:2160,否则得到的图像看起来是变形了的

画一张“画布”

获取截图自定义尺寸在前面两步已经完成了,要自定义缩略图子图位置可以先做一个特定大小的画布,然后按意愿将截图放置于特定的位置,这样就得到一个自定义形式的缩略图了。

  • 生成一张尺寸为3840x2160、颜色为0xcaff70的“画布”
ffmpeg -f lavfi -i color=c=0xcaff70:s=3840x2160 -vframes 1 blank.jpg -y

blank.jpg
Tips!

  1. 颜色可以是16进制,也可以用对应的单词代表,具体参见文档,以及可以使用random随机给定颜色
  2. 参数s是明确的分辨率,不能像scale那样可以只指定一边

图像叠加放置

有了画布,那接下来就是在画布上放置图像了,使用overlay滤镜。

  • 在一张颜色为0xcaff70、尺寸为3840x2160图像上的(100,10)位置(左上角为原点,向下是y,向右是x)放置一张分辨率为1920x1080的图像
ffmpeg -i blank.jpg -i input.jpg -vfoverlay=100:10 output.jpg -y

output.jpg

  • 在画布上放置两张图像,第一张图位置是(100,10),第二张图位置是(500,500),均以画布左上角为原点
ffmpeg -i blank.jpg -i input1.jpg -i input2.jpg -filter_complex [0:v][1:v]overlay=100:10[img];[img][2:v]overlay=500:500 output.jpg -y

output.jpg
Tips!

  1. 多个输入文件混合处理,使用filter_complex,连续处理时使用分号隔开,如果最后要分别得到不同产物,可以用-map来分配,具体参见文档labeled filtergraph outputs部分。更详细的还可以看这里
  2. 为了避免叠加过程中多次生成图片,在这里使用了label,也就是示例中的[img],可以简单理解为它是一个中间的临时变量,存放上一步的产物,然后可以在后续过程中作为输入或输出使用,这里是用作输入。
  3. label可以作为输入,但文件输入的使用形式是[file_index:stream_specifier],也就是示例中的[0:v]这样的部分,意思是选取第1张图片,更多详细使用选项见官方文档

添加文字

至此,现在可以生成自定义形式的缩略图了,但是光是图怎么行,还得加上文字对吧!
加文字使用drawtext滤镜

ffmpeg -i blank.jpg -i input1.jpg -i input2.jpg -filter_complex [0:v][1:v]overlay=100:10[img];[img][2:v]overlay=500:500[img];[img]drawtext=fontfile="Microsoft YaHei Mono.ttf":fontcolor=#cb0f70:fontsize=175:x=3200:y=1800:text='weimo' output_with_text.jpg -y

output_with_text.jpg
Tips!

  1. fontfile用于指定字体文件,如果字体不放在执行命令所在路径,那么请在命令中使用完整路径,另外请使用单引号将它引起来以避免空格带来其他的问题。如果你的文字含有中文,建议使用支持中文的字体,否则会乱码。
  2. fontcolor用来设定颜色,这和前面的color一样用法,这里使用#也是其写法之一
  3. fontsize是文字的大小,xy是位置,请注意文字大小和位置的搭配使用,否则会出现文字只有部分的情况
  4. text部分就是你要输入的文字了,同样建议使用单引号引起来。
  5. 不使用text参数,还可以使用textfile=text.txt来传入文字,这样直接支持文字换行,参见

Q:如果使用text且要换行怎么办?
A:根据ffmpeg源代码,当遇到\n,\v,\f,\r时会新起一行。那么输入weimo^L66666这样的text就能将字符换行了,这个^L并不是两个字符,它是\f,可以键入Ctrl+L,或者按住Alt键,然后输入它的ascii码12后松开Alt键,以输入这个特殊字符。四个字符对应的ascii码刚好是10、11、12、13,使用Alt输入的方法还能输入中文,比如依次按下Alt+4+5+2+1+7+Alt会得到字符。另外还可以把不同行当作新的输入来处理换行需求,具体参见StockOverflow的提问
output_with_multilines_text.jpg

结语

通过上述的命令,可自行定义一个样式,然后基于ffmpeg截图后合成一张缩略图(以及带上文字水印)。
其他需要注意的地方:

  • 根据视频尺寸计算合适的画布大小
  • 根据画布尺寸和缩略图尺寸计算相对位置
  • 根据文字大小和文字数量排布确定文字位置
  • 尽量使用label减少中间文件的产生

如有错误请指正~

自用脚本

写了一个powershell脚本,需要手动指定视频路径
复制保存为ps1脚本,设定视频路径,并将字体放在和视频一个位置,运行脚本即可
脚本可以自行扩展,字体文件似乎用完整路径会有问题,原因未知。
这个脚本是截图缩放到720p和360p,然后按上面说的逻辑拼图而成。
考虑到视频末尾会有黑屏现象,因此在减了300帧进行计算
通过时间截图更快,所以脚本获取了帧数后计算了每张图的对应时间,然后基于时间截图
代码和效果图如下:

$video_path = 'E:\我的莫格利男孩50.mp4'
$video_name = Split-Path -leaf $video_path
$video_folder = Split-Path -Path $video_path
$font_path = 'Microsoft YaHei Mono.ttf'
&cd $video_folder
$text_cmd = 'drawtext=fontfile=''{1}'':fontcolor=#50616d:fontsize=75:x=(w-text_w)/2:y=(360-text_h*2)/2:text=''{0}'',drawtext=fontfile=''{1}'':fontcolor=#50616d:fontsize=75:x=(w-text_w)/2:y=(360+text_h)/2:text=''@weimo#blog''' -f $video_name, $font_path
$mode = "大小图模式"
$pic_number_big = 4
$pic_number_small = 14
$pic_number = $pic_number_big + $pic_number_small
$ffmpeg_output = &ffmpeg -i $video_path -map 0:v:0 -c copy -f null - 2>&1
$ffmpeg_output
$pattern=[regex]"frame.*?(\d+)"
$f = $pattern.Matches($ffmpeg_output)
$framenumber = [int]$f[$f.count - 1].Groups[1].Value - 300
$pattern = [regex]"(\d+) fps"
$f = $pattern.Matches($ffmpeg_output)
$framerate = [int]$f.Groups[1].Value
$stepnumber = [math]::Floor($framenumber / $pic_number)
for($i=0;$i -lt $pic_number_big;$i++)
{
    $frametime = $stepnumber * ($i + 1) / $framerate
    $ffmpeg_cmd = '&ffmpeg -ss {0} -i "{1}" -vframes 1 -vf "scale=1280:-1" -q:v 2 "{2}.jpg" -y' -f $frametime, $video_path, ($i + 1)
    iex $ffmpeg_cmd
}
for($i=$pic_number_big;$i -lt $pic_number;$i++)
{
    $frametime = $stepnumber * ($i + 1) / $framerate
    $ffmpeg_cmd = '&ffmpeg -ss {0} -i "{1}" -vframes 1 -vf "scale=640:-1" -q:v 2 "{2}.jpg" -y' -f $frametime, $video_path, ($i + 1)
    iex $ffmpeg_cmd
}
$xy_large = (0,0),(1280,0),(2560,360),(640,720)
$xy_samll = (2560,0),(3200,0),(0,720),(1920,720),(0,1080),(1920,1080),(2560,1080),(3200,1080),(0,1440),(640,1440),(1280,1440),(1920,1440),(2560,1440),(3200,1440)
$xy = $xy_large + $xy_samll
for($i=0;$i -lt $pic_number;$i++)
{
$xy[$i][9] += 360
}
&ffmpeg -f lavfi -i color=c=#bce672:s=3840x2160 -vframes 1 backround.jpg -y
$ipart = ""
for($i=0;$i -lt $pic_number;$i++)
{
    $ipart = $ipart + '-i {0}.jpg ' -f ($i + 1)
}
$fcpart = ""
for($i=0;$i -lt $pic_number;$i++)
{
    if($i -eq 0){
    $fcpart = $fcpart + '[{0}:v][{1}:v]overlay={2}:{3}[img];' -f $i, ($i + 1), $xy[$i][0], $xy[$i][10]
    }
    elseif($i -ne ($pic_number - 1)){
    $fcpart = $fcpart + '[img][{0}:v]overlay={1}:{2}[img];' -f ($i + 1), $xy[$i][0], $xy[$i][11]
    }
    else{
    $fcpart = $fcpart + '[img][{0}:v]overlay={1}:{2}[img];[img]{3}' -f ($i + 1), $xy[$i][0], $xy[$i][12], $text_cmd
    }
}
$cmd = '&ffmpeg -i backround.jpg {0} -filter_complex "{1}" -q:v 2 {2}[email protected] -y' -f $ipart, $fcpart, $video_name
iex $cmd
for($i=0;$i -lt $pic_number;$i++)
{
$del_cmd = '&Remove-Item {0}.jpg ' -f ($i + 1)
iex $del_cmd
}
&Remove-Item backround.jpg

效果图

我的莫格利男孩50.mp4_thumbnail@weimo.jpg

powershell脚本真是不好写...

颜色选取来源于中国传统颜色手册