Windows版FFmpeg使用及B站视频下载示例python源码

news2025/5/11 8:24:05

Windows版FFmpeg使用及B站视频下载示例python源码

FFmpeg介绍和下载

FFmpeg 是一个功能强大、灵活且广泛使用的多媒体处理工具,无论是在专业领域还是日常使用中,都能满足各种多媒体处理需求。FFmpeg 是一个开源项目,遵循 LGPL 或 GPL 许可。这意味着你可以免费使用、修改和分发它。组成:

ffmpeg:这是 FFmpeg 的核心工具,用于处理多媒体文件的转换、录制、播放等操作。

ffplay:一个简单的多媒体播放器,用于播放视频和音频文件。

ffprobe:用于分析多媒体文件的元数据,例如文件格式、编码信息、时长等。

FFmpeg 支持几乎所有常见的视频和音频格式,如 MP4、AVI、MKV、MOV、WAV、MP3、FLV 等。它还支持多种编解码器,如 H.264、H.265、AAC、MP3 等。

使用方式

FFmpeg 是一个命令行工具,可以通过命令行参数来执行各种操作。例如:

    转换格式:ffmpeg -i input.mp4 -c:v libx264 output.avi

    提取音频:ffmpeg -i video.mp4 -q:a 0 -map a audio.mp3

常用参数

输入输出相关

-i <input>:指定输入文件。

-f <format>:强制指定输入或输出文件格式。

-y:自动覆盖输出文件。

-n:禁止覆盖输出文件。

编码器和解码器

-c:v <codec>:指定视频编解码器。

-c:a <codec>:指定音频编解码器。

-c copy:直接拷贝流,不进行重新编码。

更多情况可见https://ffmpeg.org/ffmpeg.html#Trancoding

也可以通过编程接口(如Python、C/C++)调用其功能,方便集成到其他软件中。

Windows版本的FFmpeg下载

打开 FFmpeg 官网https://ffmpeg.org/,选择Download(下载)。

选择左边的 release builds(发布版本)

可以选择下载上面红色圈中的 release-full 版本,

选择带 shared 的还是不带 shared 的版本,其实都是可以的。

下载后,解压使用。解压进入 bin 目录

带 shared 的里面,多了 include、lib 目录。把 FFmpeg 依赖的模块包单独的放在的 lib 目录中。ffmpeg.exe,ffplay.exe,ffprobe.exe 作为可执行文件的入口,文件体积很小,他们在运行的时候,如果需要,会到 lib 中调用相应的功能。

不带 shared 的里面,bin 目录中有 ffmpeg.exe,ffplay.exe,ffprobe.exe 三个可执行文件,每个 exe 的体积都稍大一点,因为它已经把相关的需要用的模块包编译到exe里面去了。不带 shared 的版本,单文件可以方便使用。

python代码bilibili(B站)下载示例源码

下面给出bilibili(B站)上西游记精彩花絮

https://www.bilibili.com/video/BV1gX4y1P7Va/?spm_id_from=333.788.recommend_more_video.10

使用python及第三方模块requests实现

先介绍代码中使用的模块

requests模块。这个模块是用来发送HTTP请求的,比如GET、POST等,非常常用。方便与 Web API 进行交互。requests是第三方库,不是Python的标准库,需要额外安装,通常用pip install requests来安装。所以这个需要用户自己安装。

json模块。这个模块用于处理JSON数据,比如解析和生成JSON。例如将 Python 字典转换为 JSON 字符串,或将 JSON 字符串解析为 Python 对象。json是Python的内置库,从Python 2.6开始就存在了,所以不需要安装。

pprint模块,全称是Pretty Print,用于美化输出数据结构,比如字典和列表,使其更易读。这个也是Python的标准库,属于内置模块,不需要安装。

re模块,正则表达式模块,支持字符串匹配、搜索、替换等操作,常用于文本处理和模式匹配。。同样,这是Python内置的,无需安装。

os模块,提供了与操作系统交互的功能,比如文件和目录操作、环境变量等。是内置的,不需要额外安装。

subprocess模块,用于运行外部命令或程序。允许生成新的进程,连接输入/输出/错误管道,并获取返回码。是Python标准库的一部分,不需要安装。

sys模块,提供对Python解释器相关的操作,比如访问命令行参数、退出程序、获取模块路径等。属于内置模块,无需安装。

urllib.parse.urlparse。urllib.parse是用于处理URL的模块,urlparse是其中的一个函数,用来解析URL。urllib是Python的标准库,所以不需要安装。在Python 3中,urllib被分成了几个子模块,比如urllib.request、urllib.parse等。

代码逻辑如下

发送HTTP请求获取网页内容。

从网页内容中解析出视频和音频的URL。

下载视频和音频文件。

使用FFmpeg工具合并视频和音频文件。

注意,该代码通用性极低,不能下载B站所有视频,仅能下载‌B站未加密、无分片(如.m3u8索引文件)、非会员/付费‌的公开视频。

源码如下:

import requests
import json
import pprint
import re
import os
import subprocess
import sys
from urllib.parse import urlparse

# 全局常量定义
SAVE_DIR = r'D:\bilibili' #视频存放路径设置
FFMPEG_PATH = r'D:\ffmpeg-7.1-full_build\bin\ffmpeg.exe'  # 修改为实际路径
ILLEGAL_CHARS = r'[<>:"/\\|?*\x00-\x1F]'

def clean_filename(filename):
    """清理文件名中的非法字符"""
    return re.sub(ILLEGAL_CHARS, '_', filename).strip()

def getResponse(url):
    """获取url响应体(带重试机制)"""
    # 设置请求头以模拟浏览器访问
    headers = {
        'referer': 'https://www.bilibili.com/',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36'
    }
    try:
        response = requests.get(url=url, headers=headers, timeout=20)
        response.raise_for_status()
        return response
    except RequestException as e:
        raise RuntimeError(f"网络请求失败: {str(e)}") from e

def parseResponse(url):
    """解析响应体"""
    try:
        # 验证域名
        if 'bilibili.com' not in urlparse(url).netloc:
            raise ValueError("非B站视频链接")

        response = getResponse(url)
        
        # 提取视频信息
        html_data_match = re.search(r'<script>window\.__playinfo__=(.*?)</script>', response.text)
        if not html_data_match:
            raise ValueError("未找到视频数据")
        
        try:
            jsonData = json.loads(html_data_match.group(1))
        except json.JSONDecodeError as e:
            raise ValueError("视频数据解析失败") from e

        # 提取标题
        title_match = re.search(r'<title data-vue-meta="true">(.*?)</title>', response.text)
        if not title_match:
            raise ValueError("未找到视频标题")
        
        videoTitle = clean_filename(title_match.group(0).split('>')[1].split('<')[0])
        
        # 验证媒体流数据
        try:
            audioUrl = jsonData['data']['dash']['audio'][0]['baseUrl']
            videoUrl = jsonData['data']['dash']['video'][0]['baseUrl']
        except (KeyError, IndexError) as e:
            raise ValueError("视频流信息不完整") from e

        return {
            'videoTitle': videoTitle,
            'audioUrl': audioUrl,
            'videoUrl': videoUrl,
        }
    except Exception as e:
        raise RuntimeError(f"解析响应失败: {str(e)}") from e

def saveMedia(fileName, content, mediaType):
    """保存媒体文件"""
    try:
        os.makedirs(SAVE_DIR, exist_ok=True)
        safe_name = f"{clean_filename(fileName)}.{mediaType}"
        full_path = os.path.join(SAVE_DIR, safe_name)
        
        with open(full_path, 'wb') as f:
            f.write(content)
        print(f"[√] {mediaType.upper()}保存成功: {safe_name}")
        return full_path
    except (IOError, OSError) as e:
        raise RuntimeError(f"文件保存失败: {str(e)}") from e

def AvMerge(Mp3Path, Mp4Path, savePath):
    """合并音视频"""
    try:
        if not os.path.isfile(FFMPEG_PATH):
            raise FileNotFoundError("FFmpeg路径不存在")

        print("[!] 开始合并音视频...")
        cmd = [
            FFMPEG_PATH,
            '-y',  # 覆盖输出文件
            '-i', Mp4Path,
            '-i', Mp3Path,
            '-c:v', 'copy',
            '-c:a', 'aac',
            '-strict', 'experimental',
            savePath
        ]
        
        try:
            subprocess.run(
                cmd,
                check=True,
                stdout=subprocess.DEVNULL,
                stderr=subprocess.DEVNULL
            )
        except subprocess.CalledProcessError as e:
            raise RuntimeError(f"合并失败(错误码 {e.returncode})") from e

        print(f"[√] 合并完成: {os.path.basename(savePath)}")
        
        # 清理临时文件
        for path in [Mp3Path, Mp4Path]:
            try:
                if os.path.exists(path):
                    os.remove(path)
                    print(f"[!] 已清理临时文件: {os.path.basename(path)}")
            except Exception as e:
                print(f"[!] 清理文件失败: {str(e)}")
    except Exception as e:
        raise RuntimeError(f"合并过程出错: {str(e)}") from e

def main():
    try:
        url = input("请输入B站视频url地址: ").strip()
        if not url.startswith(('http://', 'https://')):
            raise ValueError("请输入有效的URL地址")

        videoInfo = parseResponse(url)
        base_name = videoInfo['videoTitle']

        # 下载音频
        audio_content = getResponse(videoInfo['audioUrl']).content
        mp3_path = saveMedia(base_name, audio_content, 'mp3')
        
        # 下载视频
        video_content = getResponse(videoInfo['videoUrl']).content
        mp4_path = saveMedia(base_name, video_content, 'mp4')

        # 合并文件
        merged_path = os.path.join(SAVE_DIR, f'merged_{base_name}.mp4')
        AvMerge(mp3_path, mp4_path, merged_path)

        print(f"[√] 全部操作已完成!保存路径: {merged_path}")
    except Exception as e:
        print(f"[X] 程序运行出错: {str(e)}")
        sys.exit(1)

if __name__ == '__main__':
    main()

说明

其中,代码行:FFMPEG_PATH = r"D:\ffmpeg-7.1-full_build\bin\ffmpeg.exe"  # 修改为你的实际路径

若使用不带 shared 的版本,可将bin 目录中的 ffmpeg.exe文件,直接拷贝到这个程序的文件夹中,可将其改为:FFMPEG_PATH = r".\ffmpeg.exe"  # 修改为你的实际路径

、Python网络爬虫入门 https://blog.csdn.net/cnds123/article/details/121868887

OK!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2308705.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

飞书考勤Excel导入到自己系统

此篇主要用于记录Excel一行中&#xff0c;单条数据的日期拿取&#xff0c;并判断上下班打卡情况。代码可能满足不了大部分需求&#xff0c;目前只够本公司用&#xff0c;如果需要&#xff0c;可以参考。 需要把飞书月度汇总的考勤表导入系统中可以参考下。 下图为需要获取的年…

【leetcode hot 100 560】和为K的子数组

解法一&#xff1a;用左右指针寻找字串&#xff0c;如果和>k&#xff0c;则减少一个数&#xff08;left&#xff09;&#xff1b;如果和<k&#xff0c;则加上一个数&#xff08;right&#xff09;。 class Solution {public int subarraySum(int[] nums, int k) {int nu…

EGO-Planner的无人机视觉选择(yolov5和yolov8)

EGO-Planner的无人机视觉选择&#xff08;yolov5和yolov8&#xff09; 效果 yolov5检测效果 yolov8检测效果 一、YOLOv8 vs YOLOv5&#xff1a;关键差异解析 1. 训练效率&#xff1a;为何YOLOv8更快&#xff1f; 架构轻量化 YOLOv8采用C2f模块&#xff08;Cross Stage Partia…

性能测试分析和调优

步骤 性能调优的步骤 性能调优的步骤&#xff1a; 1.确定问题&#xff1a;根据性能测试的结果来分析确定bug。–测试人员职责 2.分析原因&#xff1a;分析问题产生的原因。----开发人员职责 3.给出解决方案&#xff1a;可以是修改软件配置、增加硬件资源配置、修改代码等----…

阿里云oss文件上传springboot若依java

一、第一步 引入依赖 <!-- 阿里云OSS --> <dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId> </dependency> 二、第二步 application.yml #阿里云oss服务配置 aliyun:oss:endpoint: …

使用create_sql_query_chain工具根据自然语言问题生成SQL查询,踩坑版

1. 开启调试模式 from langchain import debugdebug True # 启用调试模式说明&#xff1a; 这里从 langchain 库中导入了一个名为 debug 的变量&#xff08;或模块&#xff09;&#xff0c;然后将它设置为 True。这通常用来启用调试模式&#xff0c;方便开发者在程序运行时看…

无人机自主导航与避障技术!

自主导航的实现 环境感知&#xff1a;通过传感器&#xff08;如摄像头、激光雷达、超声波传感器等&#xff09;获取周围环境信息。 地图构建&#xff1a;利用SLAM&#xff08;同步定位与地图构建&#xff09;技术&#xff0c;实时生成环境地图并确定无人机的位置。 路径规划…

密码学(哈希函数)

4.1 Hash函数与数据完整性 数据完整性&#xff1a; 检测传输消息&#xff08;加密或未加密&#xff09;的修改。 密码学Hash函数&#xff1a; 构建某些数据的简短“指纹”&#xff1b;如果数据被篡改&#xff0c;则该指纹&#xff08;以高概率&#xff09;不再有效。Hash函数…

嵌入式开发工程师笔试面试指南-HR面试常见问题汇总

在嵌入式领域的招聘面试中,HR 通过一系列精心设计的问题,全面考察候选人的综合素质、专业能力以及与岗位的匹配度。以下从多个关键方面汇总了 HR 在嵌入式面试中常见的问题。 ** 一、语言表达方面 请简单介绍一下你自己这是面试开场常见问题,旨在让候选人做一个自我展示,…

Docker 搭建 Gitlab 服务器 (完整详细版)

参考 Docker 搭建 Gitlab 服务器 (完整详细版)_docker gitlab-CSDN博客 Docker 安装 (完整详细版)_docker安装-CSDN博客 Docker 日常命令大全(完整详细版)_docker命令-CSDN博客 1、Gitlab镜像 # 查找Gitlab镜像 docker search gitlab # 拉取Gitlab镜像 docker pull gitlab/g…

MongoDB安全管理

MongoDB如何鉴权 保证数据的安全性是数据库的重大职责之一。与大多数数据库一样&#xff0c;MongoDB内部提供了一套完整的权限防护机制。如下例所示&#xff1a; mongo --host 127.0.0.1 --port 27017 --username someone --password errorpass --authenticationDatabasestor…

架构案例:从初创互联网公司到分布式存储与反应式编程框架的架构设计

文章目录 引言一、初创互联网公司架构演化案例1. 万级日订单级别架构2. 十万级日订单级别架构3. 百万级日订单级别架构 二、分布式存储系统 Doris 架构案例三、反应式编程框架架构案例总结 引言 分布式架构 今天我们将探讨三种不同类型的架构案例&#xff0c;分别探讨 一个初…

神经网络之CNN图像识别(torch api 调用)

1.简介 CNN 是受生物学上感受野机制启发而提出的。它通过卷积操作自动提取数据中的特征&#xff0c;避免了传统机器学习方法中复杂的特征工程过程&#xff0c;能够自动学习到数据中的有效特征&#xff0c;从而进行分类、识别等任务。 2.结构 2.1卷积&#xff1a; 假设你有一…

使用Truffle、Ganache、MetaMask、Vue+Web3完成的一个简单区块链项目

文章目录 概要初始化Truffle项目创建编写合约编译合约配置Ganache修改truffle-config.js文件编写迁移文件部署合约使用Truffle 控制台使用MetaMask和VueWeb3与链交互 概要 使用Truffle、Ganache、MetaMask、VueWeb3完成的一个简单区块链项目。 初始化Truffle项目 安装好truf…

学生管理前端

文章目录 首页student.html查询功能 首页 SpringBoot前端html页面放在static文件夹下&#xff1a;/src/main/resources/static 默认首页为index.html&#xff0c;我们可以用两个超链接或者两个button跳转到对应的页面。这里只是单纯的跳转页面&#xff0c;不需要提交表单等其…

DeepSeek 助力 Vue3 开发:打造丝滑的网格布局(Grid Layout)

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

lvgl运行机制分析

lv_timer_handler() 是 LVGL 的“心脏”&#xff1a;这个函数会依次做以下事情&#xff1a; 处理定时器&#xff08;如动画、延迟回调&#xff09;。 读取输入设备&#xff08;如触摸屏、按键的状态&#xff09;。 刷新脏区域&#xff08;仅重绘屏幕上发生变化的区域&#xf…

8 SpringBoot进阶(上):AOP(面向切面编程技术)、AOP案例之统一操作日志

文章目录 前言1. AOP基础1.1 AOP概述: 什么是AOP?1.2 AOP快速入门1.3 Spring AOP核心中的相关术语(面试)2. AOP进阶2.1 通知类型2.1.1 @Around:环绕通知,此注解标注的通知方法在目标方法前、后都被执行(通知的代码在业务方法之前和之后都有)2.1.2 @Before:前置通知,此…

day01_Java基础

文章目录 day01_Java基础一、今日课程内容二、Java语言概述&#xff08;了解&#xff09;1、Java语言概述2、为什么要学习Java语言3、Java平台版本说明4、Java特点 三、Java环境搭建&#xff08;操作&#xff09;1、JDK和JRE的概述2、JDK的下载和安装3、IDEA的安装4、IDEA的启动…

cursor 弹出在签出前,请清理仓库工作树 窗口

问题出现的背景&#xff1a;是因为我有两台电脑开发&#xff0c;提交后&#xff0c;另一个电脑的代码是旧的&#xff0c;这个时候我想拉取最新的代码&#xff0c;就会出现如下弹窗&#xff0c;因为这个代码暂存区有记录或者工作区有代码的修改&#xff0c;所以有冲突&#xff0…