V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
aynakeya
V2EX  ›  分享创造

利用 b 站二压, 30fps 和 60fps 下显示不同的画面

  •  2
     
  •   aynakeya · 144 天前 · 2496 次点击
    这是一个创建于 144 天前的主题,其中的信息可能已经有所发展或是发生改变。

    效果图

    简单来说,当一个高 FPS 的视频压缩为较低 FPS 的视频时,会选择某些帧作为关键帧插入。

    B 站提供了 30fps 或 60fps 的视频。

    因此,我们可以创建一个 120fps 的视频,然后在第1+4n 帧插入你希望在 30fps 下显示的内容,其余帧则插入你希望在 60fps 下显示的内容。

    这样,在阿 b 二压后,30fps 和 60fps 的视频就会显示不同的画面。

    至于“1+4n”这个公式的由来。

    可以首先制作一个每帧都标有序号的 120fps 视频。然后使用 ffmpeg 将视频转换为 30fps ,观察哪些帧被保留,从而确定关键帧。

    proof of concept

    懒得传 gist 了

    import cv2
    
    class Fps120FrameReader:
        def __init__(self, filename):
            self.src = cv2.VideoCapture(filename)
            self.framerate = int(self.src.get(cv2.CAP_PROP_FPS))
            if self.framerate not in [30,60,120]:
                raise Exception(f"not support frame rate other than 30, 60, 120, framerate {self.framerate}")
            self.current_frame = 0
            self.frame = None
    
        def read(self):
            if self.current_frame % (120 // self.framerate) == 0:
                ok, self.frame = self.src.read()
                if not ok:
                    self.frame = None
            self.current_frame +=1
            return self.frame
    
        def close(self):
            return self.src.release()
    
        @property
        def size(self):
            return int(self.src.get(cv2.CAP_PROP_FRAME_WIDTH)),int(self.src.get(cv2.CAP_PROP_FRAME_HEIGHT))
    
    
    
    readerA = Fps120FrameReader('igotsmoke.mp4')
    readerB = Fps120FrameReader('benkui.mp4')
    
    assert readerA.size == readerB.size
    
    fourcc = cv2.VideoWriter_fourcc(*'mp4v')
    out = cv2.VideoWriter('output_video_C.mp4', fourcc, 120, readerA.size)
    
    frame_count = 0
    while True:
        frameA = readerA.read()
        frameB = readerB.read()
    
        if frameA is None or frameB is None:
            break
    
        if frame_count % 4 == 1:
            out.write(frameA)
        else:
            out.write(frameB)
    
        frame_count += 1
    
    readerA.close()
    readerB.close()
    out.release()
    
    print("ok")
    
    16 条回复    2024-07-04 10:57:29 +08:00
    ReZer0
        1
    ReZer0  
       144 天前
    WOW ,我有一个大胆的想法!(指上传未过审的番剧和电影
    lany
        2
    lany  
       144 天前
    还能这样玩
    V2SD
        3
    V2SD  
       144 天前
    好思路!不过那正常看不就会全是画面闪现吗,审核能过嘛
    aynakeya
        4
    aynakeya  
    OP
       144 天前   ❤️ 1
    @V2SD 30fps 和 60fps 都不会闪现,只有 120fps 才会闪
    darkengine
        5
    darkengine  
       144 天前
    好奇问下,这样的视频 size 会比普通的 120hz 视频要大挺多?
    MakizonoFY
        6
    MakizonoFY  
       144 天前   ❤️ 1
    B 站看片指日可待
    blankmiss
        7
    blankmiss  
       144 天前
    额 我在 B 站上看到有人演示过 凤姐 和 热巴 那个视频对吧
    Plating
        8
    Plating  
       144 天前
    可惜不能直播,彩 6 狂喜
    MRG0
        9
    MRG0  
       144 天前
    在 b 站看过这个分析
    zhw2590582
        10
    zhw2590582  
       144 天前
    有点意思
    yuzo555
        11
    yuzo555  
       144 天前   ❤️ 1
    这视频得牛大一个吧,相邻帧之间毫无关联性,什么编码能优化这个
    cslive
        12
    cslive  
       144 天前
    大会员专属视频,之前 b 站已经有人发过,大会员看的跟普通看的视频不一样,也是用 op 发的这个原理
    HeyWeGo
        13
    HeyWeGo  
       144 天前
    这...是不是就说平行宇宙!
    zthxxx
        14
    zthxxx  
       144 天前
    @yuzo555 没关系的,因为二压之后抽出来的就是正常视频流的序列帧了
    7gugu
        15
    7gugu  
       144 天前 via iPhone
    我去这个也太牛皮了吧
    jpyl0423
        16
    jpyl0423  
       143 天前
    音频也能这样处理吗
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   6044 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 02:09 · PVG 10:09 · LAX 18:09 · JFK 21:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.