65.9K
CodeProject 正在变化。 阅读更多。
Home

通过自动标记的标记导航房地产视频

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (1投票)

2021 年 4 月 26 日

CPOL

7分钟阅读

viewsIcon

2564

在本文中,您将学习如何通过 Cloudinary 上的自动化为视频序列添加标签,并检测视频中的内容,例如公寓。

引言

一图胜千言,而对于 视频 来说,这句话同样适用。根据 Forrester Research 的 James McQuivey 博士的说法,一分钟的视频相当于 180 万字的价值。这就是为什么在线商店依赖富媒体来推广产品和销售。图像和视频能让顾客切实感受到购买的参与感——无论是汽车、度假小屋还是公寓租赁——从而让您的业务脱颖而出。

毫无疑问,视觉媒体在房地产行业拥有巨大的影响力,它为访客的“永远的家”描绘了一幅理想化的图景。重要的是,视频可以在潜在客户开始与房地产经纪人接触进行实地考察等流程之前,提供有关房产的详细信息。

线性视频很有用,但增强它以实现类似图像库的导航功能,并直接跳转到感兴趣的点,则是一个巨大的优势。传统上,作为网页开发者,您会通过软件手动导航线性视频来添加标记和导航点,从而实现这种增强。自动化这些任务将大大节省时间和劳力。

可以考虑 Cloudinary 等基于云的服务,它们提供流畅的自动化流程和高级功能。您的网站访客将非常欢迎这种便捷的方式,让他们能够轻松地浏览您应用程序中的视频并找到他们感兴趣的特定内容。

本文将在以下部分介绍该过程

理解需求

自动为视频打标签的过程包含哪些内容?

首先,您必须逐帧分析视频,以选择和标记帧中的对象。这有点像处理图像,但您将处理一组链接在一起的图像。对于桌面应用程序来说,这相当直接。但是,对于自助式 Web 应用程序来说,这意味着您必须解决以下挑战:

  • 上传和存储大型视频文件。
  • 处理和编辑,例如模糊和应用各种数字滤镜。
  • 用于对象识别的人工智能。
  • 边缘部署和内容缓存用于视频服务。

最重要的是,文件必须易于管理和组织。通常,您需要通过 URL 和受控访问来共享视频。您可能还需要实现评分和反馈功能。

最后,您必须优化视频,以便在网站或应用程序上快速渲染。

如何才能在不创建一堆独立的工具和服务的情况下完成所有这些工作?

视频标记

本节将向您展示如何通过 Cloudinary 为房地产网站自动标记视频,从而让访客能够通过视频导航房产。具体来说,您将学习如何执行以下两项任务:

  • 上传视频并在云端托管。
  • 使用 Videojs-markers 自动为视频打标签,以展示特定房间的外观,如下图所示。

配套代码可在 GitHub 上找到。

上传、标记和存储视频文件

您的团队中可能有人负责制作视频。为了模拟这个示例,我首先从 Unsplash 下载了三张图片,分别描绘了厨房、卧室和客厅。然后,我使用 iMovie 创建了一个简单的房地产视频,每个画面持续四秒,最终形成一个 12 秒的视频(可在 GitHub 上 查看视频)。

之后,我执行了以下操作:

1. 我注册了一个免费的 Cloudinary 账户,并启用了 Google 自动视频打标签插件,这是 Cloudinary 自动为视频打标签的基础服务。您可以通过 Cloudinary 网站管理插件,如下图所示。

2. 我回到仪表盘,记下了我的云名称和 API 凭证。

现在,我拥有开始编码所需的一切。

3. 作为使用 Cloudinary Node.js SDK 的第一步,我使用以下命令安装了 Cloudinary npm 包: npm install cloudinary

4. 我创建了 common.js 模块,导入了 npm 包,然后配置了 API 凭证。

var cloudinary = require('cloudinary').v2;

cloudinary.config({ 
    cloud_name: '<YOUR_CLOUD_NAME>', 
    api_key: '<YOUR_KEY>', 
    api_secret: '<YOUR_SECRET>' 
});

exports.cloudinary = cloudinary;

5. 我创建了 uploadVideo.js 文件,该文件引用了 common.js 文件并调用了 Cloudinary SDK 中的 upload 函数。

var common = require('./common.js');

common.cloudinary.uploader.upload('./video/house.mp4', { 
        resource_type: 'video', 
        categorization: 'google_video_tagging',
        auto_tagging: 0.5 
    },
    (error, result) => {
        console.log(result, error) 

        // Display public id of the uploaded video
        console.log('Your public id is: ' + result['public_id']);
    }
);

upload 函数接受多个 参数。至少,您必须指定视频的文件路径。您还可以添加上传参数。在本例中,我添加了三个:

  • resource_type:此参数通知 Cloudinary 您正在上传的内容类型。可能的值为 imagerawvideoauto
  • categorization:此参数包含一组插件。您可以指定以下值之一:google_video_taggingazure_video_indexer
  • auto_tagging:此参数指定在为资源打标签之前所需的置信度分数。

在我的示例中,Cloudinary 会将置信度高于 50% 的所有标签添加到资源中。请注意,此打标签与 Cloudinary 中的内容分类有关,即 Cloudinary 根据识别出的视频内容添加标签。

您还必须将一个回调函数传递给 upload 函数,我利用它来报告来自 Cloudinary 的响应。这是一个典型的响应:

{
  asset_id: 'dc5b3c8891d9ad974455839816ba34af',
  public_id: 'dosfm1nxpjkystb3uqtj',
  version: 1610890792,
  version_id: '76121d9c617365ffbc24f15e2b043ba1',
  signature: 'ffd2f8daadd2f8a71097bdb69699548e1fc45c5f',
  width: 1280,
  height: 720,
  format: 'mp4',
  resource_type: 'video',
  created_at: '2021-01-17T13:39:52Z',
  tags: [],
  pages: 0,
  bytes: 18216284,
  type: 'upload',
  etag: 'bc2f54f085adaa0f365437027d0cc6f3',
  placeholder: false,
  url: 'http://res.cloudinary.com/futuresoftpl/video/upload/v1610890792/dosfm1nxpjkystb3uqtj.mp4',
  secure_url: 'https://res.cloudinary.com/futuresoftpl/video/upload/v1610890792/dosfm1nxpjkystb3uqtj.mp4',
  info: { categorization: { google_video_tagging: [Object] } },
  audio: {},
  video: {
    pix_format: 'yuv420p',
    codec: 'h264',
    level: 31,
    profile: 'High',
    bit_rate: '12032377',
    dar: '16:9',
    time_base: '1/30000'
  },
  frame_rate: 29.97002997002997,
  bit_rate: 12132057,
  duration: 12.012,
  rotation: 0,
  original_filename: 'house',
  nb_frames: 360
}

这是包含您上传资源所有详细信息的 JSON 对象,包括您可以在网站中引用的公共 URL 以及您 Cloudinary 账户中资源的公共标识符。我的回调函数会显示此公共标识符,因为我稍后将用它来获取视频标签。

从处理后的视频中提取标签

upload 函数的响应 **不** 显示标签。相反,它只在 info.categorization.google_video_tagging 属性中显示 [Object]。您需要额外的代码来揭示这些标签。具体来说,您必须遍历生成的 JSON。

result['info']['categorization']['google_video_tagging']['data']

为了避免重复上传视频,我使用了 Cloudinary Admin APIapi.resource 方法,该方法在给定公共标识符和资源类型的情况下,返回资源的详细信息。

这是视频的示例(请参阅配套代码中的 getMarkers.js)。

var common = require('./common.js');

public_id = 'dosfm1nxpjkystb3uqtj';

common.cloudinary.api.resource(public_id, {resource_type: "video"}, 
    (error, result) => {
    // Get categorization data
    categorizationData = result['info']['categorization']
        ['google_video_tagging']['data'];    

    console.log(categorizationData)       
    });
});

运行此代码将为您提供关于您视频中检测到的内容的全部信息。这是我视频响应的选定部分:

[
  {
    tag: 'interior design',
    categories: [],
    start_time_offset: 0,
    end_time_offset: 11.978633,
    confidence: 0.9868196845054626,
    shot_level: false
  },
  {
    tag: 'apartment',
    categories: [ 'building' ],
    start_time_offset: 0,
    end_time_offset: 11.978633,
    confidence: 0.7973060011863708,
    shot_level: false
  },
  {
    tag: 'house',
    categories: [ 'building' ],
    start_time_offset: 8.008,
    end_time_offset: 11.978633,
    confidence: 0.8208440542221069,
    shot_level: true
  },
  {
    tag: 'wall',
    categories: [],
    start_time_offset: 4.004,
    end_time_offset: 7.974633,
    confidence: 0.5453928709030151,
    shot_level: true
  },
  {
    tag: 'living room',
    categories: [ 'room' ],
    start_time_offset: 0,
    end_time_offset: 3.970633,
    confidence: 0.4006035029888153,
    shot_level: true
  },
  {
    tag: 'living room',
    categories: [ 'room' ],
    start_time_offset: 4.004,
    end_time_offset: 7.974633,
    confidence: 0.5230793952941895,
    shot_level: true
  },
  {
    tag: 'kitchen',
    categories: [ 'room' ],
    start_time_offset: 0,
    end_time_offset: 3.970633,
    confidence: 0.9755304455757141,
    shot_level: true
  },
  {
    tag: 'bedroom',
    categories: [ 'room' ],
    start_time_offset: 4.004,
    end_time_offset: 7.974633,
    confidence: 0.7389670610427856,
    shot_level: true
  },
  {
    tag: 'real estate',
    categories: [],
    start_time_offset: 8.008,
    end_time_offset: 11.978633,
    confidence: 0.8142818212509155,
    shot_level: true
  },
]

看 Cloudinary 是如何巧妙地提供视频内容摘要的?下一节将向您展示如何使用响应中的标签创建导航标记。

我使用 Videojs-markers 渲染了视频标记。他们网站上的示例显示,要添加一个标记,您必须指定几个对象,每个对象包含两个值:标记出现的时间和描述(文本)。

Cloudinary API 返回包含六个值的对象,其中我只需要两个:tagstart_time_offset。在此示例中,第一个用于标记文本;第二个用于标记的开始时间。

此外,Cloudinary API 包含了我不需要的标签,因为我的视频只描绘了厨房、卧室和客厅。因此,我使用 underscore npm 包(npm install underscore)过滤掉了所有其他标签,然后修改了 getMarkers.js,如下所示。

var common = require('./common.js');
var _ = require('underscore');

public_id = 'dosfm1nxpjkystb3uqtj';

common.cloudinary.api.resource(public_id, {resource_type: "video"}, (error, result) => {
    // Get categorization data
    categorizationData = result['info']['categorization']['google_video_tagging']['data'];        

    // Define rooms
    var rooms = ['kitchen', 'bedroom', 'living room'];

    // Get markers for each room
    // Use underscore to filter "tag" (get last element only)
    markers = [];
    rooms.forEach((room) => {        
        data = _.where(categorizationData, {'tag': room}).pop();

        marker = {
            'time': data['start_time_offset'],
            'text': data['tag']
        }

        markers.push(marker);        
    });

    console.log(markers)    
});

The method now returns the list of markers we can use along with videojs-markers:

[
  { time: 0, text: 'kitchen' },
  { time: 4.004, text: 'bedroom' },
  { time: 8.008, text: 'living room' }
]

在现实世界中,Cloudinary 会生成数千个标签,您需要有适当的机制来管理它们。要对结果进行分区,您可以使用 max_resultsderived_next_cursor 选项,这些选项会与 resource_type 选项一起传递。

渲染带标记的视频

为了将所有内容连接起来并实现本文顶部房间照片所示的结果,我创建了一个简单的网站(请参阅配套代码中的 website/index.html),该网站引用了 videojs-markers 和其他一些辅助 JavaScript 代码。在 body 部分,一个 <video> HTML 标签渲染了示例房地产视频。

<video id="house" controls class="video-js vjs-default-skin" 
    width="800" height="600">
    <source src="../video/house.mp4" type="video/mp4">    
</video>

为了优化视频渲染,您可以将 src 标签替换为 Cloudinary 的标签,在我的情况下,它如下所示:

https://res.cloudinary.com/demo/video/upload/v1614368895/house_tour.mp4

您可以通过在 URL 中添加参数,使用 视频转换 进一步优化视频。

之后,我使用 JavaScript 视频播放器添加了标记。

<script>
    var player = optimizer.videoJS;

    player.markers({
        markerTip:{
            display: true,
            text: function(marker) {
                return marker.text;
            }
        },
        markers: [
            { time: 0, text: 'kitchen' },
            { time: 4.004, text: 'bedroom' },
            { time: 8.008, text: 'living room' }
        ]
    });
</script>

Cloudinary 现在已为我的视频添加了标记。

处理大型视频文件

上述视频示例很短,上传和渲染速度很快,不需要额外的工具。但是,对于长视频文件,一个好的做法是配置异步上传,并使用 通知 URL 来告知您上传何时完成。

要在网站上渲染视频,您还可以通过 Cloudinary 视频播放器 使用自适应比特率流。

继续下一步

您现在已经学会了如何通过 Cloudinary 上的自动化为视频序列添加标签,并检测视频中的内容,例如公寓。从那里,您可以创建标记来帮助您的网站访客浏览视频。

Cloudinary API 及其全面的 AI 方法使得过程非常简单,增强了带有已标记、易于导航的视频的应用程序,这对于一定会回访的访客来说是一大福音。除了房地产,您还可以采用相同的技术为活动、培训课程等视频添加标签和结构。

请在您的下一个项目尝试一下!首先,请 注册 一个免费的 Cloudinary 账户。

© . All rights reserved.