整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Safari 神器,手机平板都能用,我们找到了 14

Safari 神器,手机平板都能用,我们找到了 14 个超实用浏览器插件

iOS 15/iPadOS 15 之后,移动端的 Safari 有了对扩展插件的全面支持,在各种插件的辅助之下,移动端 Safari 变得更加全面,体验也愈发接近桌面端,这对那些希望用 iPad 替代笔记本作为生产力工具的群体而言,是个极大的升级点。

如今新系统也已正式推出,Safari 插件的数量也增至一个较为可观的水平,是时候为大家推荐一些好用的插件了,下文我以 iPad 上的 Safari 为例给各位进行演示。

首先,iPad Safari 的扩展插件与桌面端的 Safari 插件不同,它其实是个 app,Safari 插件功能是在它原生 app 派生出的一部分功能。

因此我们要到 App Store 去下载 app,然后在 Safari 当中开启相关拓展插件功能。

苹果为这类 Safari 扩展插件设立了推荐专区,在「系统设置-Safari-扩展-更多扩展」中可以看到整个专区页面。

地区不同,推荐的插件内容也有所不同。

1. Momentum

这是一个启动页美化工具,设置启用之后,每次打开新的标签页时都会展示一张好看的图片作为背景,还会显示当前时间,还能设立 To Do 任务和常用网页。

免费版本会为用户每天更新一张背景图,如果想用自己相册里的图片则需要升级成付费版本。

2. AdBlock

官方放出的免费插件排行榜中,粗略算算至少有 4 成是广告拦截插件,AdBlock 作为此类工具中的老面孔,我自然也把它作为首选。

需要注意的是,此类插件一律被归为内容拦截器,开启的方式与其他插件有所不同,在域名栏左侧「大小/Aa 按键」中调用 ,点击该键就能看到内容拦截器的开关。

之所以叫内容拦截器,是因为它们拦截的不光是广告,还可以把违规网站、跟踪程序、评论等恼人的内容拦下来,还用户一个干净纯粹的页面。

实际效果中规中矩,它可以拦下部分 Banner 类广告,还有流媒体上的贴片广告,但偶尔还是会出现一些漏网之鱼。

3. Apollo for Reddit

这是个 Reddit 论坛的第三方 app,作用类似于第三方微博客户端,它们针对 Safari 开发的插件名叫 Open in Apollo,顾名思义,当它侦测到你在 Safari 浏览器上打开 Reddit 页面时,会自动跳转至 Apollo app 界面,作用简单粗暴。

4. 1Password

它也算是老牌密码储存器了,它所做的 Safari 扩展插件的功能,也就是为网站自动生成或填充对应平台账号的密码。

若你更常用苹果自带的密钥卡包,那还能省下安装 Safari 插件的步骤,可以自动识别和填充密码。

5. Firefox Focus

这是火狐开发的一个无痕浏览器,它的 Safari 插件也被归为内容拦截器,但它并不拦截广告,而是截下广告跟踪,让广告商没办法通过你点击了哪些页面来分析你的喜好和习惯。可以配合上面的 AdBlock 一同使用。

6. Turn Off the Lights for Safari

有了这个插件,可以在大部分视频网站上,把除视频窗口的一切内容低亮化,类似于流媒体网站上常见的关灯模式。

7. StartPage.ai

我们在网上冲着浪,不自觉发现自己已经打开了数十个页面,在桌面端要关闭多个页面,有键鼠的帮助也还算简单,但在移动端可就没那么方便了。

StartPage.ai 所做的,就是打开一个新的标签页,该页展示的是当前所有页面,有哪些网站一目了然,关闭页面的按键也足够大,方便手指点摁。不过它与前面推荐的 Momentum 插件同属启动页工具,二者只能选其一。

8. DForce

Safari 本身支持系统原生的夜间模式,功能栏会根据系统改变浅色或深色背景,但网页具体页面并不会随之改变,DForce 所做的,就是让页面内容也变成深色,暗光下阅读的时候多少能起到护眼的效果。

▲ 插件启用前后对比

它提供了免费版本,个人觉得基本够用,付费版只是多了些自定义选项。

9. Keyword Search

这个软件就为解决一件事,Safari 地址栏进行特定网站的快速搜索。

听起来还是有点复杂,我举个例子你很快就明白了,譬如我想在爱范儿搜索某篇文章,基本操作是在地址栏输入「ifanr.com」,然后进入爱范儿网页里点击搜索,输入关键词按回车,最终才会跳转至结果页面。

但有了 Keyword Search,我们可以提前设置好关键字,譬如用「i」设置为爱范儿站内搜索指令的快捷词,后面接上我们想要搜索的关键词,按下回车即可。

若你正在学习日语,或者你经常逛一些日文网站,那不让试试这款插件。它的功能类似于 Mate,只不过它专攻日语翻译。

另外,该插件开发者为用户预设好了数个常用网站的捷径,当你安装好这个插件后,不妨输入「y Rick Astley」试试。

10. Mate

它本身是个翻译 app,所以在 Safari 上也是充当翻译插件的角色存在,不过用户只能选取字段进行翻译,并不能把一键翻译整个页面的内容,看着跟其 198 元的售价不太相符。

不过这一需求,可以用系统自带的翻译功能满足,当我们浏览全外文网站时,地址栏左边会出现翻译按键,按一下就能把整个页面转换成中文,虽然准确度差强人意,不过可以起到辅助理解的作用,聊胜于无。

11. 10tenJapanese

若你正在学习日语,或者你经常逛一些日文网站,那不让试试这款插件。它的功能类似于 Mate,只不过它专攻日语翻译。

启用该插件后,页面会出现一个光标,长按并拖动至日文字上,就会实时显示出它的英文释义,确实它也有局限性,看来以后学日语之前,还得先学好英文。

12. JSBox

移动端的 Safari 本身没有自带检查器,JSBox 插件的出现弥补了这一缺陷。不过代码呈现的形式不太友好,点开就把整个页面挡住了。

用户在这上面还可以设立一些 Javascript 脚本,执行一些简单的功能是没有问题的。

13. Notebook

有了这个插件,用户可以不离开 Safari 网页,直接开始笔记,支持 Apple Pencil,还有页面截图功能,之后在 app 里进行更细致的划重点、圈段落等细致操作,也很不错,算是原生备忘录的一个补充。

14. 网页二维码生成

它能将当前浏览的页面生成二维码,方便你把它分享出去。

还可以辅助线下宣传,譬如大学社团可以通过它,把赛事活动的报名页面做成二维码,放在线下报名海报上。

目前看来,移动端 Safari 的插件生态处于数量尚可,质量参差的状态,如果你奔着某种特定功能上 App Store 去搜索的话,大概率会无功而返,只能去插件专区里一个一个点开去找,操作略微繁琐,整体来看还有较高的上升空间。

不过当你花费一段时间,把 Safari 打造得更符合你的使用习惯后,所得到的正向反馈,也足以把一切辛劳统统抵消,这不正是折腾 app 的乐趣所在吗?

着入职时间变长,工作不断的深入,在需要同时处理多个任务的同时,打开几十上百个浏览器 Tab 页就必不可少了,而我的工作几乎都是在各种浏览器 Tab 页之间来回切换,如写文档、学习新知识、处理 Bug 单流转、上线等流程,所以我需要对浏览器的 Tab 页进行精细化管理,以达到精细化管理工作流程的目的,于是乎,我对于浏览器的使用变成了下面几个阶段:

Chrome - 杂乱无章阶段

Chrome - 进行适当整理

Edge - 竖向侧边栏

但是无论浏览器层面提供多少这样或那样的辅助,但毕竟浏览器的职责主要是负责帮助你更好、更快、更高效的浏览网页,并非是帮你管理知识和工作流程,所以如果需要个性化定制的需求,就得自己上手开发啦!毕竟作为程序员,自己动手,丰衣足食嘛 。

需求分析

我希望能够开发一个 Chrome 浏览器插件,当前其他浏览器如 Edge、Firefox、Brave,以及其他所有使用 Chromimum 开发的浏览器都是支持 Chrome 插件格式的,而这几大浏览器几乎占据了近 83% 左右的桌面端浏览器市场,所以这个 Chrome 插件可以在我喜欢的浏览器上运行。

以下是 2020.3 到 2021.3 的桌面端浏览器占比数据

这个浏览器支持传统的插件点击弹出栏,以及每次打开一个新 Tab 都能展示我的应用,这样能够帮助我随时了解我当前正在进行的工作,大致形式如下:

弹出栏:

新 Tab:

针对上面需求的形式不知道大家是否比较熟悉了?没错,这个插件的框架形式和 掘金 的插件类似,我们看下掘金的 Chrome 插件:

弹出框:

新 Tab:

也就是说,在看完本次文章,你基本上拥有了开发一个掘金插件的能力,心动了?

随便一提,我们本次开发插件的技术栈如下:

  • React + TypeScript,基于 Create-React-App 脚手架搭建

通过先进的技术栈来编写 Chrome 插件。

前置知识

Chrome 插件实际上包含几个部分:

  • manifest.json 文件,相当于整个项目的入口,里面记录着此插件的 icon 图标展示、弹出框样式文件、新建 Tab 逻辑、选项逻辑、内容脚本逻辑等
  • background.js,此脚本是在整个浏览器启动或者插件加载之后就会运行的一个脚本文件,它运行在 ServiceWorker 里面,通常用于进行一些前置的数据 storage 存储操作,可以操作所有的 Chrome API
  • popup.html,插件的弹出框展示的模板内容,可以通过 CSS 控制样式,JavaScript 控制逻辑
  • options.html,右键插件 icon 时弹出菜单页,点击菜单页里面的选项打开的页面
  • content.js,此脚本是在你打开一个新的网页的时候,Chrome 浏览器为这个网页注入的一个脚本文件,用于辅助此网页和你的插件进行一个通信,因为插件的运行环境是经过沙盒隔离的,无法直接操作到 DOM,所以需要通过 content 脚本操作 DOM,然后发送给到插件的处理逻辑

上述 5 大文件组成了一个 Chrome 插件所需要的必须元素,逻辑关系如下:

image.png

可以看到,其实开发一个 Chrome 的插件也是使用 HTML/JavaScript/CSS 这些知识,只不过使用场景,每种 JavaScript 使用的权限与功能、操作的 API 不太一样,那么既然是使用基本的 Web 基础技术,我们就可以借助更为上层的 Web 开发框架如 React 等来将 Chrome 插件的开发上升到一个现代化的程度。

最简化插件

确保你安装了最新版的 Node.js,然后在命令行中运行如下命令:

npx create-react-app chrome-react-extension --template typescript

初始化好项目、安装完依赖之后,我们可以看到 CRA 产生的模板代码,其中就有我们需要的 public/manifest.json 文件:

当然内容并没有我们上图那样丰富我们需要做一些修改,将内容改为如下内容:

{
   "name": "Chrome React Extension",
   "description": "使用 React TypeScript 构建 Chrome 扩展",
   "version": "1.0",
   "manifest_version": 3,
   "action": {
       "default_popup": "index.html",
       "default_title": "Open the popup"
   },
   "icons": {
       "16": "logo192.png",
       "48": "logo192.png",
       "128": "logo192.png"
   }
}

上述的字段说明如下:

  • name:插件的名字,展示在 Chrome 插件 icon 里面,以及插件市场等
  • description:简介插件时干嘛的
  • version:插件当前的版本
  • manifest_version:当前使用的 manifest 文件的版本,Chrome 插件最小的 manifest 版本是 V3
  • action:控制点击插件 icon 时的需要反应的动作(action),这里我们设置 hover 时展示的文字为 default_title,点击打开展示的内容为 index.html
  • icons:为展示在 Chrome 插件里面的图标

实际上 Chrome 插件只能理解原生的 JavaScript,CSS,HTML 等, 所以我们使用 React 学完之后,需要进行构建,将构建的产物打包给到浏览器插件去加载使用,在构建时,还有一个需要注意的就是,为了保证最优化性能,CRA 的脚本在构建时会将一些小的 JS 文件等,内联到 HTML 文件中,而不是打包成独立的 JS 文件,在 Chrome 插件的运行环境下,这种形式的 HTML 是不支持的,会触发插件的 CSP(内容安全策略)错误。

所以为了测试我们的插件当前效果,我们修改构建脚本,在 package.json 里面:

"scripts": {
    "start": "react-scripts start",
    "build": "INLINE_RUNTIME_CHUNK=false react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

通过设置 INLINE_RUNTIME_CHUNK=false 确保所有的 JS 会构建成独立的文件,然后引入到 HTML 中加载使用。

一切准备完毕,是时候构建我们的 React 应用了~ 在命令行中运行如下命令:

npm run build

会发现内容构建输出在 build/xxx 下面,包含 manifest.json、index.html、对应的 JS/CSS 文件还有图片等,其中 manifest 中索引了 index.html 来作为点击插件时的 Popup 的展示页,这个时候我们就可以使用 Chrome 加载我们构建好的文件,来查看插件运行效果了:

我们打开扩展程序面板,设置开发者模式,然后点击加载文件,选择我们的 build 文件地址加载:

Magic !我们可以在浏览器里面看到我们的插件,并使用它了,一个最简化插件完成!

当然这里我们虽然能够使用 React/TypeScript 以及一切现代的 Web 开发技术来写插件,但是目前没有很好的方式能够实时的进行开发-查看效果,就是我们常见的 HMR、Live Reload 这种技术暂时还没有很好的支持到 Chrome 插件的开发,所以每次我们需要查看编写的效果都需要构建之后点击插件查看。

当然如果纯针对 UI 或者和 Chrome API 无关的逻辑,那么你可以放心的直接在 Web 里面开发,等到开发完毕再构建到 Chrome 插件预览即可。

定制新 Tab 逻辑

我们之前的逻辑是,只要新开一个 Tab,那么就会访问我们提供的页面,类似掘金的插件,而且我们也主要到,其实针对 Popup 页面只是几个按钮,而重头戏都在新 Tab 页界面展示,也就是我们这里其实需要一个多页应用?因为最终要生成页面,一个用在 Popup 页面展示,一个用在新 Tab 页展示。

但是我们知道 CRA 脚手架生成的模板是主要用于单页应用,如果需要切换到多页应用有一定的成本,但是我们的 Popup 页面实际上就只有几个按钮,所以这里可以做一层简化,即 Popup 页面直接手动写最原始的 HTML/JS/CSS,然后将重头戏、复杂的新 Tab 页的逻辑来用 React TypeScript 等现代 Web 技术来开发。

通过这样设计之后,我们的目录结构变成了如下形式:

其中 manifest.json 的逻辑变成了如下:

{
  "name": "Chrome React SEO Extension",
  "description": "The power of React and TypeScript for building interactive Chrome extensions",
  "version": "1.0",
  "manifest_version": 3,
  "action": {
    "default_popup": "./popup/index.html",
    "default_title": "Open the popup"
  },
  "chrome_url_overrides": {
    "newtab": "index.html"
  },
  "icons": {
    "16": "logo192.png",
    "48": "logo192.png",
    "128": "logo192.png"
  }
}

我们可以看到,点击 Chrome 插件弹出的页面 Popup,换成了 ./popup/index.html ,而我们新加了一个 chrome_url_overrides 字段,在 newtab 时,我们打开构建后的 index.html 文件。

通过上面的操作,我们每次打开一个新 Tab,都会展示下面的页面:

完美!我们已经实现了掘金的插件的核心思想:便捷的获取技术知识,就在你每次打开 Tab 时。

开发 Popup 页面

接下来我们尝试改造一下我们的 Popup 页面,同样是对标掘金,我们知道掘金的 Popup 页面是一个比较简单的菜单栏,里面主要是一些用于跳转到新 Tab 或者设置页的操作:

我们现在也需要实现类似的点击某个按钮,跳转到我们新 Tab 页,打开我们上一部分定制的 Tab 逻辑。

这一部分我们就需要修改 popup/index.html ,添加相关的 JS 逻辑如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Fake Juejin Extensions</title>
    <link rel="stylesheet" href="./styles.css" />
  </head>
  <body>
    <ul>
      <li class="open_new_tab">打开新标签页</li>
      <li class="go_to_github">访问 Github</li>
      <li class="go_to_settings">设置</li>
    </ul>
    <script src="popup.js"></script>
  </body>
</html>

这一次需求我们只会操作打开新标签页、访问 Github,设置我们不做操作,留给读者自己去扩展。

可以看到我们导入了 popup.js 文件,在这个 JS 文件里,我们需要完成对应打开新标签页、和访问 Github 的逻辑配置:

document.querySelector(".open_new_tab").addEventListener("click", (e)=> {
  chrome.tabs.create({}, ()=> {});
});

document.querySelector(".go_to_github").addEventListener("click", (e)=> {
  window.open("https://github.com");
});

可以看到,因为 popup.js 是运行在 Chrome 插件的沙箱环境下的,所以它能够使用到 chrome 这个 API,进行页面、浏览器等相关的操作。

当我们写入了上述逻辑之后,我们就可以点击对应的打开新标签页,访问新标签页并展示我们上一节说到的内容,访问 Github,则会跳转到 Github 页面。

使用 Content 脚本

我们已经开发了新 Tab 页,开发了 Popup 逻辑,接下来我们可以尝试一下通过 content 脚本,来实现用户页面与插件脚本进行通信,以间接的操作 DOM。

首先我们需要在 manifest.json 里面注册 content 相关的脚本:

{
  "name": "Chrome React Extension",
  // ...
  "permissions": ["activeTab", "tabs"],
  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["./static/js/content.js"]
    }
  ]
}

上述脚本通过 content_scripts 指定 content 脚本,matches 指定匹配到那些域名时,才执行这个注入脚本的逻辑,js 代表需要注入的脚本的位置,这里我们填写的为 ./static/js/content.js ,即为通过构建之后产生的 JS 内容地址。

接着我们在 Tab 页的 React 项目里面去建立与 content 脚本的通信:

import React from "react";
import "./App.css";
import { DOMMessage, DOMMessageResponse } from "./types";

function App() {
  // 前置逻辑

  React.useEffect(()=> {
    /**
     * We can't use "chrome.runtime.sendMessage" for sending messages from React.
     * For sending messages from React we need to specify which tab to send it to. */     chrome.tabs &&
      chrome.tabs.query(
        {
          active: true,
          currentWindow: true,
        },
        (tabs)=> {
          /**
           * Sends a single message to the content script(s) in the specified tab,
           * with an optional callback to run when a response is sent back.
           *
           * The runtime.onMessage event is fired in each content script running
           * in the specified tab for the current extension. */           chrome.tabs.sendMessage(
            tabs[0].id || 0,
            { type: "GET_DOM" } as DOMMessage,
            (response: DOMMessageResponse)=> {
              setTitle(response.title);
              setHeadlines(response.headlines);
            }
          );
        }
      );
  });

  return (
    // ... 模板
  );
}

export default App;

可以看到我们通过 chome API,去查询当前正在激活的 Tab 页,然后给这个 Tab 页的 content 脚本,通过 chrome.tabs.sendMessage 发了一个 { type: "GET_DOM" } 的消息。

然后我们创建对应的 content 的脚本,在 src/chromeServices 下创建 DOMEvaluator.ts

import { DOMMessage, DOMMessageResponse } from "../types";

// Function called when a new message is received const messagesFromReactAppListener=(
  msg: DOMMessage,
  sender: chrome.runtime.MessageSender,
  sendResponse: (response: DOMMessageResponse)=> void
)=> {
  console.log("[content.js]. Message received", msg);

  const headlines=Array.from(document.getElementsByTagName<"h1">("h1")).map(
    (h1)=> h1.innerText
  );

  // Prepare the response object with information about the site   const response: DOMMessageResponse={
    title: document.title,
    headlines,
  };

  sendResponse(response);
};

/**
 * Fired when a message is sent from either an extension process or a content script. */ chrome.runtime.onMessage.addListener(messagesFromReactAppListener);

这个脚本在加载的时候,通过 onMessage.addListener 监听,然后回调 messagesFromReactAppListener ,在函数里面,可以直接获取 DOM,查询这个页面中的 标题 和所有的 H1 标签,然后返回。

import React from "react";
import "./App.css";
import { DOMMessage, DOMMessageResponse } from "./types";

function App() {
  const [title, setTitle]=React.useState("");
  const [headlines, setHeadlines]=React.useState<string[]>([]);

  // ...消息通信逻辑

  return (
    // ... 模板
    <div className="App">
      <h1>SEO Extension built with React!</h1>

      <ul className="SEOForm">
        <li className="SEOValidation">
          <div className="SEOValidationField">
            <span className="SEOValidationFieldTitle">Title</span>
            <span
              className={`SEOValidationFieldStatus ${
                title.length < 30 || title.length > 65 ? "Error" : "Ok"
              }`}
            >
              {title.length} Characters
            </span>
          </div>
          <div className="SEOVAlidationFieldValue">{title}</div>
        </li>

        <li className="SEOValidation">
          <div className="SEOValidationField">
            <span className="SEOValidationFieldTitle">Main Heading</span>
            <span
              className={`SEOValidationFieldStatus ${
                headlines.length !==1 ? "Error" : "Ok"
              }`}
            >
              {headlines.length}
            </span>
          </div>
          <div className="SEOVAlidationFieldValue">
            <ul>
              {headlines.map((headline, index)=> (
                <li key={index}>{headline}</li>
              ))}
            </ul>
          </div>
        </li>
      </ul>
    </div>
  );
}

export default App;

然后扩展一下 CSS 代码:

.App {
  background: #edf0f6;
  padding: 0.5rem;
}

.SEOForm {
  list-style: none;
  margin: 0;
  box-shadow: 0 1px 3px 0 rgb(0 0 0 / 10%), 0 1px 2px 0 rgb(0 0 0 / 6%);
  background: #fff;
  padding: 1rem;
}

.SEOValidation {
  margin-bottom: 1.5rem;
}

.SEOValidationField {
  width: 100%;
  display: flex;
  justify-content: space-between;
}

.SEOValidationFieldTitle {
  font-size: 1rem;
  color: #1a202c;
  font-weight: bold;
}

.SEOValidationFieldStatus {
  color: #fff;
  padding: 0 1rem;
  height: 1.5rem;
  font-weight: bold;
  align-items: center;
  display: flex;
  border-radius: 9999px;
}

.SEOValidationFieldStatus.Error {
  background-color: #f23b3b;
}

.SEOValidationFieldStatus.Ok {
  background-color: #48d660;
}

.SEOVAlidationFieldValue {
  overflow-wrap: break-word;
  width: 100%;
  font-size: 1rem;
  margin-top: 0.5rem;
  color: #4a5568;
}

Nice!我们成功编写了新 Tab 页模板、逻辑与样式,以及创建了 Content 脚本逻辑,最后我们的展示效果如下:

然后我们需要进行代码构建,因为 content 我们使用 TypeScript 语法写,将 content 的逻辑构建为单独的 JS 输出,我们安装 craco 依赖,然后修改对应的脚本:

yarn add -D craco
// package.json
"scripts": {
    "start": "react-scripts start",
    "build": "INLINE_RUNTIME_CHUNK=false craco build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },

react-scripts 改为 craco

然后新建 craco.config.js ,添加如下内容:

module.exports={
  webpack: {
    configure: (webpackConfig, { env, paths })=> {
      return {
        ...webpackConfig,
        entry: {
          main: [
            env==="development" &&
              require.resolve("react-dev-utils/webpackHotDevClient"),
            paths.appIndexJs,
          ].filter(Boolean),
          content: "./src/chromeServices/DOMEvaluator.ts",
        },
        output: {
          ...webpackConfig.output,
          filename: "static/js/[name].js",
        },
        optimization: {
          ...webpackConfig.optimization,
          runtimeChunk: false,
        },
      };
    },
  },
};

准备完毕,开始构建:yarn`` build ,我们会发现构建目录输出如下:

写在最后

在本篇文章中,我们完整体验了使用 React+TypeScript,开发新 Tab 内容展示页以及 content 通信脚本,然后通过配置 react-scripts 为 craco 进行了分文件构建,以及直接开发原生的 popup 页,通过这种融汇的技术,成功开发出了一个类似掘金框架的 Chrome 插件。

这篇文章没有介绍的有 background 脚本,以及整体插件内容还不够完善,希望有兴趣的读者可以继续探索,将其完善。

??/ 感谢支持 /

以上便是本次分享的全部内容,希望对你有所帮助^_^

喜欢的话别忘了 分享、点赞、收藏 三连哦~

欢迎关注公众号 程序员巴士,来自字节、虾皮、招银的三端兄弟,分享编程经验、技术干货与职业规划,助你少走弯路进大厂。

时的工作中常会遇到一些系统集成的需求,需要在软件平台集成视频监控系统。而软件开发者往往不懂安防弱电系统,不知道如何在自己的软件界面中集成一些监控的实时画面。而监控厂家提供的SDK比较复杂,很难在短时间完成集成的任务。最终导致软件平台的一些功能无法实现,影响项目的质量。

本文提供的方法主要基于VLC播放器的ActiveX插件,通过这个插件,在网页中调用摄像机的RTSP流,实现图像的实时预览,音频的监听等等功能。文章以海康的IP网络摄像机为例给出具体的调用方法,供大家学习参照。

VLC软件下载

登录VLC官网 https://www.videolan.org/,选择windows(32位)版本下载。

下载VLC软件

VLC软件安装(务必勾选插件)

运行安装文件

选择软件安装位置

一定记得要勾选网页浏览器插件

完成安装

网页编辑

可选用记事本(notepad)或专业的编辑器,输入如下代码,保存为html网页文件。

<html>
<body>

<title>TESTVDEIO-1-TEST</title>
<head>
<table>
            <tbody>
            <caption>视频监控演示</caption>
        <tr>
            <td>
            <object type='application/x-vlc-plugin' pluginspage="http://www.videolan.org/" id='vlc' events='false' width="720" height="410">
    <param name='mrl' value='rtsp://admin:q66668888@172.16.200.88:554/h264/ch1/main/av_stream' />
    <param name='volume' value='50' />
    <param name='autoplay' value='true' />
    <param name='loop' value='false' />
    <param name='fullscreen' value='false' />
    <param name='controls' value='false' />
            </td>
            <td>
            <object type='application/x-vlc-plugin' pluginspage="http://www.videolan.org/" id='vlc' events='false' width="720" height="410">
    <param name='mrl' value='rtsp://admin:q66668888@172.16.200.89:554/h264/ch1/main/av_stream' />
    <param name='volume' value='50' />
    <param name='autoplay' value='true' />
    <param name='loop' value='false' />
    <param name='fullscreen' value='false' />
    <param name='controls' value='false' />
            </td>
        </tr>
         <tr>
            <td>
            <object type='application/x-vlc-plugin' pluginspage="http://www.videolan.org/" id='vlc' events='false' width="720" height="410">
    <param name='mrl' value='rtsp://admin:q66668888@172.16.200.89:554/h264/ch1/main/av_stream' />
    <param name='volume' value='50' />
    <param name='autoplay' value='true' />
    <param name='loop' value='false' />
    <param name='fullscreen' value='false' />
    <param name='controls' value='false' />
            </td>
            <td>
            <object type='application/x-vlc-plugin' pluginspage="http://www.videolan.org/" id='vlc' events='false' width="720" height="410">
    <param name='mrl' value='rtsp://admin:q66668888@172.16.200.88:554/h264/ch1/main/av_stream' />
    <param name='volume' value='50' />
    <param name='autoplay' value='true' />
    <param name='loop' value='false' />
    <param name='fullscreen' value='false' />
    <param name='controls' value='false' />
            </td>
        </tr>
    </tbody>
</table>
            </object>
</body>
</html>

代码编辑截图

海康威视RTSP调用格式


具体请参看海康专业文档

浏览器测试

先用Google Chrome浏览器测试,提示插件不支持。

Chrome浏览器提示插件不受支持

用微软IE测试,需要安装插件。

IE浏览器提示要安装ActiveX插件

确认安装插件

浏览器只显示了第一个画面。

IE浏览器显示不完整

用编辑器测试,2种内核都能正常显示。

编辑器里测试效果

改用360浏览器,呈现2X2的画面,实现最终的显示效果。

360浏览器显示的最终效果图

结语

本文参考了一些专业文章,就不一 一列出了,在这一并谢过!

由于本人水平有限,有不对的地方敬请指正。文章旨在抛砖引玉,通过讨论,相互学习,共同进步。


我是WoNew弱电蜗牛,一名从业多年的弱电工程师,在头条传播弱电专业知识和行业信息,分享工作中的经验和心得。
喜欢我的文章或视频,欢迎点赞和转发。有疑问或建议,也欢迎留言,我会尽力解答。