ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码


Posted in Python onOctober 21, 2020

安装

官网下载

http://ffmpeg.org/

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

选择需要的版本

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

在这个网址下载ffmpeg,https://github.com/BtbN/FFmpeg-Builds/releases

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

将解压后得到的以下几个文件放置在E:\FFmpeg

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

环境变量

此电脑--属性--高级系统设置--环境变量
在系统变量(也就是下面那一半)处找到新建,按如下所示的方法填写

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

再将%FFMPEG_HOME%以及%FFMPEG_HOME%\bin写入系统变量的Path中
然后一路确定即可

验证

win+R,cmd
输入ffmpeg -version

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

ffmpeg的使用

对于我将B站PC端缓存的音频mp4和视频mp4文件合并的需求,需要用到的命令为:
ffmpeg.exe -i audio1.mp4 -i video.mp4 -acodec copy -vcodec copy output.mp4
可以把mp4的文件设置成绝对路径,这样就可以转换指定路径的文件以及保存到指定路径了,比如这样:
ffmpeg.exe -i "E:\哔哩哔哩视频\ss27993\77413703\1\audio1.mp4" -i "E:\哔哩哔哩视频\ss27993\77413703\1\video.mp4" -acodec copy -vcodec copy "E:\B站导出视频\Dr.STONE石纪元\第22话宝物.mp4
通过PC端缓存的未合并的视频和音频,全都是命名为video.mp4和audio.mp4
PS:有些兄弟是导出的手机端缓存的视频和音频,是m4s格式的,方法也一样
但光有这条命令还不够,需要自己手动一个个操作,太麻烦了
因此我还需要使用Python来自动帮我完成工作

Python实现自动处理

虽然Python可以实现自动化,减少时间的浪费,但最快的还是以后记得缓存时勾选自动合并

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

文件结构

PC端缓存的视频保存的文件结构有很多种,我只是根据我碰到的情况写的,但大同小异,修改起来也不麻烦,只是再加个if和else罢了

番剧缓存结构

缓存的番剧是这种结构:

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码
ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码
ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

上面举的例子是Dr.stone石纪元,我缓存的鬼灭之刃也是如此
特点是在一个以视频ID号名称的文件夹(ss27993)后,跟着许多子文件夹(57983089等),然后在这些子文件夹中又有一个或多个子文件夹(比如1),然后缓存的视频保存在这个文件夹里,里面有一个info文件(就是json格式),还有audio1.mp4和video.mp4。
PS:
还有一个xml文件,是弹幕信息,暂时我不知道怎么处理

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

常规缓存结构

除了番剧,一般的视频缓存的结构是这样的

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码
ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

不难看出,这比番剧要少一个层级

文件信息

文件信息主要由info文件和dvi文件来记录
这两种文件都可以直接以json文件来处理,也就是,首先open函数打开文件,然后用json.load转成字典。。。
然后我还发现了一个特点是,视频和音频所在的目录下是info文件,而它的上一层目录下是dvi文件
虽然文件格式基本是一致的,但是里面的键-值关系却不一致,单集视频的名称在番剧中对应的是键Description,在其他视频中对应的是PartName
视频总的名称保存在外层的目录下的info文件或dvi文件中,番剧中对应的键是SeasonTitle,在其他视频中对应的是Title

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

具体问题具体分析,首先由于我实践得较少,这样的总结不一定对,然后以后也许也会有新的格式、新的变化

代码

具体代码

以下是我的Python代码,你可以先试试能不能用,用不了的话,可以在理解的基础上修改。理解不了的话可以看我的后面的解释,以及代码中的注释,对于运行过程中一些变量的值,我都把它放在注释中了,方便你理解。

# -*- coding = utf-8 -*-
# @time:2020/10/17/017 23:09
# Author:cyx
# @File:main.py.py
# @Software:PyCharm

# 从.info文件中获得了Title信息,但是如果其中有某些特殊字符,保存时可能出现问题
def get_correct_title(title):

  error_set = ['/', '\\', ':', '*', '?', '"', '|', '<', '>', '\b', ' ', '.']
  correct_title = title
  # print(title)
  for c in correct_title:
    if c in error_set:
      correct_title = correct_title.replace(c, '')
  return correct_title

def popen(cmd):
  # https://blog.csdn.net/qq_41451161/article/details/82901235
  try:
    popen = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    popen.wait()
    lines = popen.stdout.readlines()
    return [line.decode('gbk') for line in lines]
  except BaseException as e:
    return -1

if __name__ == '__main__':
  import os
  import json
  import subprocess

  # ffmpeg -i video.m4s -i audio.m4s -c:v copy -c:a aac -strict experimental output.mp4
  # ffmpeg.exe -i audio1.mp4 -i video.mp4 -acodec copy -vcodec copy output.mp4
  AVhao = input("请输入视频AV号:")
  superPath = "E:\\哔哩哔哩视频" + "\\" + AVhao
  partDirs = [] # 保存每P视频所在的文件夹路径
  paths = os.listdir(superPath) # 获取当前路径下所有的文件(包括文件夹)名称
  # paths = ['8','9']
  # 有时候,会莫名其妙的少了几个视频,可以通过重载来重新加载缺失的视频
  # print(paths)
  # paths
  # ['27993.info', '57983089', '58612211', '59811008', '60862133', '61898240', '62925012', '64005445', '65020725', '66013155', '66808912', '67587875', '68398229', '69175748', '70021307', '70873680', '71617211', '73379440', '74051851', '74974157', '75746600', '76619409', '77413703', '78266594', '79070874', 'cover.jpg', 'desktop.ini']
  # 获取每P视频所在的文件夹路径
  savePos = ''
  seq = []
  # 鉴于有些up主命名时毫无规律,导出后无法正常排序,只能手动排序了
  # 根据AV号名文件夹下的子文件夹的名称进行排序,但是番剧的话不是这样排序,不过番剧单集的名称很规范,不需要这样
  for p in paths:
    if '.' not in p:
      seq.append(p)
    if 'info' in p:
      # print(p)
      # p:
      # 27993.info
      info = superPath + "\\" + p
      with open(info, 'r', encoding='utf-8') as load_f:
        load_dict = json.load(load_f)
        projectTitle = load_dict['SeasonTitle']
        projectTitle = get_correct_title(projectTitle)
        savePos = 'E:\\B站导出视频\\' + projectTitle
        print('savePos: ', savePos)

    if 'dvi' in p:
      # print(p)
      # P:
      # 328738595.dvi
      dvi = superPath + "\\" + p
      with open(dvi, 'r', encoding='utf-8') as load_f:
        load_dict = json.load(load_f)
        projectTitle = load_dict['Title']
        projectTitle = get_correct_title(projectTitle)
        savePos = 'E:\\B站导出视频\\' + projectTitle
        print('savePos: ', savePos)
    # 防止文件存在时再次生成该文件夹出现错误
    try:
      os.mkdir(savePos)
      break
    except:
      pass

    subDir = superPath + "\\" + p
    if os.path.isdir(subDir):
      # print(subDir)
      # 所有子文件夹的路径保存在partDirs中
      partDirs.append(subDir)
  # print("partDirs: ",partDirs)
  # partDirs: ['E:\\哔哩哔哩视频\\ss27993\\57983089', 'E:\\哔哩哔哩视频\\ss27993\\58612211', 'E:\\哔哩哔哩视频\\ss27993\\59811008', 'E:\\哔哩哔哩视频\\ss27993\\60862133', 'E:\\哔哩哔哩视频\\ss27993\\61898240', 'E:\\哔哩哔哩视频\\ss27993\\62925012', 'E:\\哔哩哔哩视频\\ss27993\\64005445', 'E:\\哔哩哔哩视频\\ss27993\\65020725', 'E:\\哔哩哔哩视频\\ss27993\\66013155', 'E:\\哔哩哔哩视频\\ss27993\\66808912', 'E:\\哔哩哔哩视频\\ss27993\\67587875', 'E:\\哔哩哔哩视频\\ss27993\\68398229', 'E:\\哔哩哔哩视频\\ss27993\\69175748', 'E:\\哔哩哔哩视频\\ss27993\\70021307', 'E:\\哔哩哔哩视频\\ss27993\\70873680', 'E:\\哔哩哔哩视频\\ss27993\\71617211', 'E:\\哔哩哔哩视频\\ss27993\\73379440', 'E:\\哔哩哔哩视频\\ss27993\\74051851', 'E:\\哔哩哔哩视频\\ss27993\\74974157', 'E:\\哔哩哔哩视频\\ss27993\\75746600', 'E:\\哔哩哔哩视频\\ss27993\\76619409', 'E:\\哔哩哔哩视频\\ss27993\\77413703', 'E:\\哔哩哔哩视频\\ss27993\\78266594', 'E:\\哔哩哔哩视频\\ss27993\\79070874']
  videoPos = ''
  i = 0
  for p in partDirs:
    # print(p)
    # 列出子文件夹中的所有文件
    sublist = os.listdir(p)
    # 检查info文件是否在当前子文件夹中
    for file in sublist:
      # print(file)
      # file:
      # 1
      # 57983089.
      # dvi
      # cover.jpg
      # desktop.ini
      if 'info' in file:
        infoPos = p + "\\" + file
        videoPos = p
      else:
        subsubDir = p + "\\" + file
        if os.path.isdir(subsubDir):
          # print(subsubDir)
          # subsubDir: E:\哔哩哔哩视频\ss27993\57983089\1
          subsubList = os.listdir(subsubDir)
          for subsubFile in subsubList:
            if 'info' in subsubFile:
              infoPos = subsubDir + "\\" + subsubFile
              videoPos = subsubDir
              break
      with open(infoPos, 'r', encoding='utf-8') as load_f:
        load_dict = json.load(load_f)
        if 'ss' in AVhao:
          videoTitle = load_dict['Description']
        else:
          videoTitle = load_dict['PartName']

        videoTitle = get_correct_title(videoTitle)
        print('videoTitle: ', videoTitle)
        videoDir = videoPos + "\\" + 'video.mp4'
        audioDir = videoPos + "\\" + 'audio1.mp4'
        # print('videoDir: ', videoDir)
        # print('audioDir: ', audioDir)
        # videoDir: E:\哔哩哔哩视频\ss27993\74051851\1\video.mp4
        # audioDir: E:\哔哩哔哩视频\ss27993\74051851\1\audio1.mp4
        if 'ss' in AVhao:
          outDir = savePos + "\\" + videoTitle + '.mp4'
        else:
          outDir = savePos + "\\" + seq[i] + '_' + videoTitle + '.mp4'
          i += 1
        # 对于那些命名很规范的视频,可以不用自己再排序,进行一下重载,不规范的视频再把这句注释掉就好
        outDir = savePos + "\\" + videoTitle + '.mp4'
        # command = 'cd ' + superPath + '\\64 && ' # && 多名命令
        # command = 'cd ' + 'E:\\ProgramFiles\\ffmpeg' + ' && '
        command = 'E:\\FFmpeg\\bin\\ffmpeg.exe -i ' + '"' + audioDir + '"' ' -i ' + '"' + videoDir + '"'+ ' -acodec copy -vcodec copy ' + '"' + outDir + '"'
        # print("保存地址",outDir)
        # 保存地址 E:\B站导出视频\[Lynda视频]音频录制录音技巧教程(中英双语字幕)全集130课时AudioRecordingTechniques混音录音棚音乐工作室歌曲调音\98录制独奏萨克斯演奏技巧二.mp4
        # print(command)
        # command = 'E:\\FFmpeg\\bin\\ffmpeg.exe -i "E:\哔哩哔哩视频\ss27993\77413703\1\audio1.mp4" -i "E:\哔哩哔哩视频\ss27993\77413703\1\video.mp4" -acodec copy -vcodec copy "E:\B站导出视频\Dr.STONE石纪元\第22话宝物.mp4'
        # os.system(command)
        popen(command)
        # ffmpeg.exe -i audio1.mp4 -i video.mp4 -acodec copy -vcodec copy output.mp4
        break

代码说明

如你所见我的编程水平不高,模块化做的很差,不便于理解,所以有必要进行说明。
直接从main开始看起吧。

AVhao = input("请输入视频AV号:")
  superPath = "E:\\哔哩哔哩视频" + "\\" + AVhao
  partDirs = [] # 保存每P视频所在的文件夹路径
  paths = os.listdir(superPath) # 获取当前路径下所有的文件(包括文件夹)名称

首先是用input接收AV号或BV号的输入,放入AVhao变量中。
然后用superPath变量存放你需要合并的视频的根目录。比如我在B站缓存的所有视频存放在E:\哔哩哔哩视频下,注意程序中要有两条\,然后superPath就是E:\哔哩哔哩视频\AVhao
os.listdir(),括号中的参数必须是一个真实的路径,这个函数可以得到这个路径下所有的文件和文件夹的名称。
我用paths来存放E:\哔哩哔哩视频\AVhao路径下所有的文件名称和文件夹名称。
为了防止我的表达能力有限带来的理解上的不便,你可以看图,paths对应的是下图中的内容:

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

这个变量的类型是列表,所以可以用for循环来遍历。

savePos = ''
  seq = []
  for p in paths:
    if '.' not in p:
      seq.append(p)
    if 'info' in p:
      # print(p)
      # p:
      # 27993.info
      info = superPath + "\\" + p
      with open(info, 'r', encoding='utf-8') as load_f:
        load_dict = json.load(load_f)
        projectTitle = load_dict['SeasonTitle']
        projectTitle = get_correct_title(projectTitle)
        savePos = 'E:\\B站导出视频\\' + projectTitle
        print('savePos: ', savePos)

    if 'dvi' in p:
      # print(p)
      # P:
      # 328738595.dvi
      dvi = superPath + "\\" + p
      with open(dvi, 'r', encoding='utf-8') as load_f:
        load_dict = json.load(load_f)
        projectTitle = load_dict['Title']
        projectTitle = get_correct_title(projectTitle)
        savePos = 'E:\\B站导出视频\\' + projectTitle
        print('savePos: ', savePos)
    # 防止文件存在时再次生成该文件夹出现错误
    try:
      os.mkdir(savePos)
      break
    except:
      pass

    subDir = superPath + "\\" + p
    if os.path.isdir(subDir):
      # print(subDir)
      # 所有子文件夹的路径保存在partDirs中
      partDirs.append(subDir)

我设置了一个savePos变量,用来表示合并后的视频保存的位置,因为我希望将视频保存在一个我自己指定的文件夹下,同时这个文件夹的名称是这个视频的名称,比如Dr.stone石纪元。
因为想自动化操作,所以我通过缓存文件夹中的info文件和dvi文件来找到视频的名称。
使用open函数打开这两个文件中的一个,因为不确定文件结构是什么样的,所以我用了两个if语句。
然后再用json.load函数将其加载为字典,并根据对应的键读取对应的值,从而可以拼接处对应的保存地址savePos。
由于创建已经存在的同名文件夹会发生错误,为避免这种可能,我将创建目录的操作放在了try语句下。
创建目录用的是os.mkdir()函数,括号中是一个绝对路径。
然后我用subDir来表示子文件夹的名称,注意!是子文件夹,而不是文件。
我用os.path.isdir(subDir)来进行判断,如果是文件夹而不是文件的话,就加到partDirs列表中,partDirs.append(subDir)
这个列表中的每个元素都是一个子文件夹的绝对路径,比如:E:\哔哩哔哩视频\ss27993\57983089
而这个名为seq的显得很突兀,这个其实我也是后来加的,这个列表的作用在于记录当前子文件夹的名称,也就是在AVhao文件夹的下一层,如果不是番剧的话,应当有许多个文件夹分别是1、2、3等等,这些其实对应的是播放列表中的顺序。

ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码
ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码

而之所以使用if '.' not in p,因为这一层的文件夹全都是用来表示播放顺序的,因此不存在后缀名,从而也就没有“.”。

videoPos = ''
  i = 0
  for p in partDirs:
    # print(p)
    # 列出子文件夹中的所有文件
    sublist = os.listdir(p)
    # 检查info文件是否在当前子文件夹中
    for file in sublist:
      # print(file)
      # file:
      # 1
      # 57983089.
      # dvi
      # cover.jpg
      # desktop.ini
      if 'info' in file:
        infoPos = p + "\\" + file
        videoPos = p
      else:
        subsubDir = p + "\\" + file
        if os.path.isdir(subsubDir):
          # print(subsubDir)
          # subsubDir: E:\哔哩哔哩视频\ss27993\57983089\1
          subsubList = os.listdir(subsubDir)
          for subsubFile in subsubList:
            if 'info' in subsubFile:
              infoPos = subsubDir + "\\" + subsubFile
              videoPos = subsubDir
              break
      with open(infoPos, 'r', encoding='utf-8') as load_f:
        load_dict = json.load(load_f)
        if 'ss' in AVhao:
          videoTitle = load_dict['Description']
        else:
          videoTitle = load_dict['PartName']

        videoTitle = get_correct_title(videoTitle)
        print('videoTitle: ', videoTitle)
        videoDir = videoPos + "\\" + 'video.mp4'
        audioDir = videoPos + "\\" + 'audio1.mp4'
        # print('videoDir: ', videoDir)
        # print('audioDir: ', audioDir)
        # videoDir: E:\哔哩哔哩视频\ss27993\74051851\1\video.mp4
        # audioDir: E:\哔哩哔哩视频\ss27993\74051851\1\audio1.mp4
        if 'ss' in AVhao:
          outDir = savePos + "\\" + videoTitle + '.mp4'
        else:
          outDir = savePos + "\\" + seq[i] + '_' + videoTitle + '.mp4'
          i += 1
        # 对于那些命名很规范的视频,可以不用自己再排序,进行一下重载,不规范的视频再把这句注释掉就好
        outDir = savePos + "\\" + videoTitle + '.mp4'
        # command = 'cd ' + superPath + '\\64 && ' # && 多名命令
        # command = 'cd ' + 'E:\\ProgramFiles\\ffmpeg' + ' && '
        command = 'E:\\FFmpeg\\bin\\ffmpeg.exe -i ' + '"' + audioDir + '"' ' -i ' + '"' + videoDir + '"'+ ' -acodec copy -vcodec copy ' + '"' + outDir + '"'
        # print("保存地址",outDir)
        # 保存地址 E:\B站导出视频\[Lynda视频]音频录制录音技巧教程(中英双语字幕)全集130课时AudioRecordingTechniques混音录音棚音乐工作室歌曲调音\98录制独奏萨克斯演奏技巧二.mp4
        # print(command)
        # command = 'E:\\FFmpeg\\bin\\ffmpeg.exe -i "E:\哔哩哔哩视频\ss27993\77413703\1\audio1.mp4" -i "E:\哔哩哔哩视频\ss27993\77413703\1\video.mp4" -acodec copy -vcodec copy "E:\B站导出视频\Dr.STONE石纪元\第22话宝物.mp4'
        # os.system(command)
        popen(command)
        # ffmpeg.exe -i audio1.mp4 -i video.mp4 -acodec copy -vcodec copy output.mp4
        break

这一部分是我用来实现合并特定路径的视频和音频,并最终导出到指定目录的。
videoPos是待合并的视频的路径,音频文件也在这一目录下。
for p in partDirs:,在这个for循环中遍历的是partDirs列表,这个列表由前面的步骤得到,其中的每个元素都是一个路径。
接下来的这个if-else是用来区别番剧和普通视频合集的,因为它们有不同的目录结构。
infoPos用来记录包含单集视频名称的info文件的路径,然后用open函数打开这个info文件,根据AVhao中是否有ss,判断是否是番剧,如果有ss,则表明是番剧,对应的视频名称为Description键对应的值。否则的话,对应的视频名称为PartName键对应的值,但是如果是要保存为文件的话,当然不能直接以这个名称命名,否则极有可能发生错误,因此我用了一个get_correct_title函数来对标题进行重载,以确保格式正确。
videoDir和audioDir分别是待合并的视频和音频的绝对路径。
然后我根据AVhao中是否有ss,来判断是否是番剧。因为番剧的单集视频名称通常会有序号,所以我可以将输出视频的保存路径设置为保存目录加视频名.mp4。
许多up主的视频名称没有体现视频的先后顺序,这样带来的问题是导出后顺序播放时产生跳集现象。因此我用seq加下划线的方式来为视频排序。比如“1_简介.mp4”。
而对于视频名称本身有排序的情况1_1简介.mp4,这样有些奇怪,所以我们碰到这种情况时,可以直接在下面添加一个outDir = savePos + "\\" + videoTitle + '.mp4',其他情况不用时注释掉就好。
最后是用Python程序执行Dos命令,我将命令设为command变量,通过for循环,会自动生成不同的命令,然后执行命令行有两种方法,一种是导入os库,使用os.system(command),另一种是我在https://blog.csdn.net/qq_41451161/article/details/82901235借用的popen函数,这个也可以用,但需要导入subprocess库。
使用命令行上,有两个比较坑的地方,一是前面必须给出ffmpeg.exe的绝对路径,也就是E:\FFmpeg\bin\ffmpeg.exe,在Python中用是这样的,但直接在命令行中,只要输入ffmpeg.exe即可(前提是你设置好了环境变量)。第二个坑是,command赋值时,一定给路径加上引号,否则的话识别命令时会发生错误。

到此这篇关于ffmpeg+Python实现B站MP4格式音频与视频的合并示例代码的文章就介绍到这了,更多相关Python音频与视频的合并内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python实现通过shelve修改对象实例
Sep 26 Python
使用Python脚本将Bing的每日图片作为桌面的教程
May 04 Python
Django中的“惰性翻译”方法的相关使用
Jul 27 Python
Python3访问并下载网页内容的方法
Jul 28 Python
python基础教程项目五之虚拟茶话会
Apr 02 Python
pandas.dataframe中根据条件获取元素所在的位置方法(索引)
Jun 07 Python
Python 删除整个文本中的空格,并实现按行显示
Jul 24 Python
Python实现将通信达.day文件读取为DataFrame
Dec 22 Python
关于pycharm中pip版本10.0无法使用的解决办法
Oct 10 Python
Python倒排索引之查找包含某主题或单词的文件
Nov 13 Python
Python如何转换字符串大小写
Jun 04 Python
python中pandas库中DataFrame对行和列的操作使用方法示例
Jun 14 Python
运行Python编写的程序方法实例
Oct 21 #Python
Python读写csv文件流程及异常解决
Oct 20 #Python
Python脚本打包成可执行文件过程解析
Oct 20 #Python
PyQt5的QWebEngineView使用示例
Oct 20 #Python
Python测试框架:pytest学习笔记
Oct 20 #Python
如何快速一次性卸载所有python包(第三方库)呢
Oct 20 #Python
Python模块常用四种安装方式
Oct 20 #Python
You might like
在字符串中把网址改成超级链接
2006/10/09 PHP
Apache服务器无法使用的解决方法
2013/05/08 PHP
PHP 循环删除无限分类子节点的实现代码
2013/06/21 PHP
ThinkPHP应用模式扩展详解
2014/07/16 PHP
PHP访问数据库集群的方法小结
2016/03/14 PHP
php实现将数组或对象写入到文件的方法小结【三种方法】
2020/04/22 PHP
情人节专属 纯js脚本1k大小的3D玫瑰效果
2012/02/11 Javascript
JS等比例缩小图片尺寸的实例
2013/02/27 Javascript
js 时间格式与时间戳的相互转换示例代码
2013/12/25 Javascript
js使用onmousemove和onmouseout获取鼠标坐标的方法
2015/03/31 Javascript
Javascript实现苹果悬浮虚拟按钮
2016/04/10 Javascript
JavaScript DOM节点操作方法总结
2016/08/23 Javascript
jquery 追加元素append、prepend、before、after用法与区别分析
2016/12/02 Javascript
Jquery Easyui搜索框组件SearchBox使用详解(19)
2016/12/17 Javascript
基于bootstrap风格的弹框插件
2016/12/28 Javascript
angularJs中datatable实现代码
2017/06/03 Javascript
Require.js的基本用法详解
2017/07/03 Javascript
JS实现unicode和UTF-8之间的互相转换互转
2017/07/05 Javascript
浅谈箭头函数写法在ReactJs中的使用
2017/08/22 Javascript
CSS3结合jQuery实现动画效果及回调函数的实例
2017/12/27 jQuery
微信小程序实现列表下拉刷新上拉加载
2020/07/29 Javascript
基于JS实现数字动态变化显示效果附源码
2019/07/18 Javascript
vue遍历对象中的数组取值示例
2019/11/07 Javascript
基于aotu.js实现微信自动添加通讯录中的联系人功能
2020/05/28 Javascript
Jquery $.map使用方法实例详解
2020/09/01 jQuery
[05:49]DOTA2-DPC中国联赛 正赛 Elephant vs LBZS 选手采访
2021/03/11 DOTA
python django使用haystack:全文检索的框架(实例讲解)
2017/09/27 Python
Django进阶之CSRF的解决
2018/08/01 Python
python 魔法函数实例及解析
2019/09/25 Python
基于python3.7利用Motor来异步读写Mongodb提高效率(推荐)
2020/04/29 Python
python Cartopy的基础使用详解
2020/11/01 Python
预防艾滋病宣传标语
2014/06/25 职场文书
小区的门卫岗位职责
2014/10/01 职场文书
会议欢迎词
2015/01/23 职场文书
2015年重阳节活动总结
2015/03/24 职场文书
2015年护理工作总结范文
2015/04/03 职场文书