max2012 发表于 2021-9-21 10:29

哔哩哔哩视频缓存合并perl脚本工具

哔哩哔哩上的视频是可以下载缓存至手机的,在sdcard的app的download目录下。
使用雷电模拟器在PC上安装,这样下载视频的缓存文件可直接复制到PC上进行合并处理。
哔哩哔哩缓存视频是是视频与音频分开存放,而且各种文件混乱的放在一起,缓存了也无法直接使用,于是个人写了个小脚本解决了这个问题,共享给大家使用。
另外,后面发现各种下载与合并都一体化的工具不少,很好用,都懒得用这个脚本了,有需求的自行下载使用吧。

1. 脚本使用环境,perl 版有一定要求,最好保持一致,没用python写是担心perl快遗忘掉,重新温习下
perl --version

This is perl 5, version 16, subversion 3 (v5.16.3) built for MSWin32-x64-multi-thread
(with 1 registered patch, see perl -V for more detail)

Copyright 1987-2012, Larry Wall

Binary build 1604 provided by ActiveState

2. 脚本合并视频依赖ffmpeg可执行文件,这个有点大,自行去官网下载后放置脚本能找到的位置(sytem目录或脚本一起的目录都可以)
3. 在脚本中修改实际的视频处理文件位置,跑脚本就能得到分门别类合并好的视频文件
4. 针对不同的视频可能有需要兼容性处理,个人遇到的都适配完毕,但大部分应该没问题,没遇有需要就后续在加强一下即可

脚本源码:
#!/usr/bin/perl
use strict;
use warnings;
use File::Spec;
use File::Basename;
use File::Path qw(make_path remove_tree);
use JSON;
use Encode;


sub getDirectoryFiles
{
        my $cwd = shift;
        return unless(defined $cwd);
        my @arryFiles=();
        if ( -f $cwd )
        {
                push(@arryFiles,File::Spec->catfile($cwd,""));
        }
        else
        {
                my @dirs = (File::Spec->catdir($cwd,"."));
                while (my $dir = pop(@dirs))
                {
                        local *DH;
                        next if (!opendir(DH, $dir));
                        for(readdir(DH))
                        {
                                next if ($_ eq '.' || $_ eq '..');
                                my $file =File::Spec->catdir($dir,$_);
                                if (!-l $file && -d _)
                {
                  push(@dirs, $file);
                  next;
                }
                push(@arryFiles, $file);
                        }
                        closedir DH;
                }
        }
        return sort(@arryFiles);
}

sub utf8ToGb2312
{
    return encode("gb2312", decode("utf8", shift));
}

sub normalizeFilePath
{
    $_=shift;
    s/["\?\*\|<>]//g;
    return $_;
}

sub mergeVideo
{
    my $bin_ffmpeg='ffmpeg';
    my $mergeFilePath=normalizeFilePath(shift);
    my $audioFilePath=normalizeFilePath(shift);
    my $videoFilePath=normalizeFilePath(shift);
    my $outDir=dirname($mergeFilePath);

    if (-e $mergeFilePath) {
      return;
    }

    if ( !-d "$outDir" )
    {
      make_path($outDir);
    }
    system("$bin_ffmpeg -i $audioFilePath -i $videoFilePath-codec copy \"$mergeFilePath\"");
    #if ($?!=0) {exit 1;}
    #exit;
}

sub doBilibiliVideo
{
    my $outDir=shift;
    for(getDirectoryFiles(shift))
    {
      next unless(/(.*)\\entry\.json$/);
      print $_."\n";

      my $videoRootDir=$1;
      my $filePath = $_;

      #next if (!open(FILE, '<:encoding(UTF-8)', $filePath));
      next if (!open(FILE, $filePath));
      my $content = do { local $/=undef; <FILE>; };
      close(FILE);
      my $json = JSON->new;
      my $data = $json->decode($content);
      my $type_tag = utf8ToGb2312($data->{'type_tag'});
      print $type_tag."\n";
      my $title = utf8ToGb2312($data->{'title'});
      print $title."\n";
      my $page = utf8ToGb2312($data->{'page_data'}->{'page'});
      print $page."\n";
      my $part = utf8ToGb2312($data->{'page_data'}->{'part'});
      print $part."\n";

      my $audioFilePath=File::Spec->catfile($videoRootDir,$type_tag,'audio.m4s');
      my $videoFilePath=File::Spec->catfile($videoRootDir,$type_tag,'video.m4s');
      print $audioFilePath."\n";
      print $videoFilePath."\n";

      my $mergeFileName=$page.'_'.$part.'.mp4';
      my $mergeFilePath=File::Spec->catfile($outDir,$title,$mergeFileName);
      print $mergeFilePath."\n";

      mergeVideo($mergeFilePath,$audioFilePath,$videoFilePath);

      #last;
    }
}

my $rootDir='.';

# 指定处理后输出文件目录
my $outDir='.';

# 指定下载视频缓存文件位置,此处是雷电模拟器共享缓存到PC的位置
$rootDir='C:\Users\admin\Documents\leidian64\Pictures\download';
doBilibiliVideo $outDir, $rootDir;

w360 发表于 2021-9-21 15:42

看看咋用
页: [1]
查看完整版本: 哔哩哔哩视频缓存合并perl脚本工具