首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Angular 从入坑到挖坑 - 路由守卫连连看

Angular 从入坑到挖坑 - 路由守卫连连看

作者头像
程序员宇说
发布于 2020-06-04 01:59:16
发布于 2020-06-04 01:59:16
4.6K00
代码可运行
举报
文章被收录于专栏:程序员宇说程序员宇说
运行总次数:0
代码可运行

一、Overview

Angular 入坑记录的笔记第六篇,介绍 Angular 路由模块中关于路由守卫的相关知识点,了解常用到的路由守卫接口,知道如何通过实现路由守卫接口来实现特定的功能需求,以及实现对于特性模块的惰性加载

对应官方文档地址:

配套代码地址:angular-practice/src/router-combat

二、Contents

  1. Angular 从入坑到弃坑 - Angular 使用入门
  2. Angular 从入坑到挖坑 - 组件食用指南
  3. Angular 从入坑到挖坑 - 表单控件概览
  4. Angular 从入坑到挖坑 - HTTP 请求概览
  5. Angular 从入坑到挖坑 - Router 路由使用入门指北
  6. Angular 从入坑到挖坑 - 路由守卫连连看

三、Knowledge Graph

四、Step by Step

4.1、基础准备

重复上一篇笔记的内容,搭建一个包含路由配置的 Angualr 项目

新建四个组件,分别对应于三个实际使用到的页面与一个设置为通配路由的 404 页面

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 危机中心页面
ng g component crisis-list

-- 英雄中心页面
ng g component hero-list

-- 英雄相亲页面
ng g component hero-detail

-- 404 页面
ng g component page-not-found 

在 app-routing.module.ts 文件中完成对于项目路由的定义,这里包含了对于路由的重定向、通配路由,以及通过动态路由进行参数传递的使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

// 引入组件
import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { HeroListComponent } from './hero-list/hero-list.component';
import { HeroDetailComponent } from './hero-detail/hero-detail.component';
import { PageNotFoundComponent } from './page-not-found/page-not-found.component';

const routes: Routes = [
  {
    path: 'crisis-center',
    component: CrisisListComponent,
  },
  {
    path: 'heroes',
    component: HeroListComponent,
  },
  {
    path: 'hero/:id',
    component: HeroDetailComponent,
  },
  {
    path: '',
    redirectTo: '/heroes',
    pathMatch: 'full',
  },
  {
    path: '**',
    component: PageNotFoundComponent,
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule { }

之后,在根组件中,添加 router-outlet 标签用来声明路由在页面上渲染的出口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<h1>Angular Router</h1>
<nav>
  <a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a> &nbsp;&nbsp;
  <a routerLink="/heroes" routerLinkActive="active">Heroes</a>
</nav>
<router-outlet></router-outlet>
4.2、路由守卫

在 Angular 中,路由守卫主要可以解决以下的问题

  • 对于用户访问页面的权限校验(是否已经登录?已经登录的角色是否有权限进入?)
  • 在跳转到组件前获取某些必须的数据
  • 离开页面时,提示用户是否保存未提交的修改

Angular 路由模块提供了如下的几个接口用来帮助我们解决上面的问题

  • CanActivate:用来处理系统跳转到到某个路由地址的操作(判断是否可以进行访问)
  • CanActivateChild:功能同 CanActivate,只不过针对的是子路由
  • CanDeactivate:用来处理从当前路由离开的情况(判断是否存在未提交的信息)
  • CanLoad:是否允许通过延迟加载的方式加载某个模块

在添加了路由守卫之后,通过路由守卫返回的值,从而达到我们控制路由的目的

  • true:导航将会继续
  • false:导航将会中断,用户停留在当前的页面或者是跳转到指定的页面
  • UrlTree:取消当前的导航,并导航到路由守卫返回的这个 UrlTree 上(一个新的路由信息)
4.2.1、CanActivate:认证授权

在实现路由守卫之前,可以通过 Angular CLI 来生成路由守卫的接口实现类,通过命令行,在 app/auth 路径下生成一个授权守卫类,CLI 会提示我们选择继承的路由守卫接口,这里选择 CanActivate 即可

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ng g guard auth/auth

在 AuthGuard 这个路由守卫类中,我们模拟了是否允许访问一个路由地址的认证授权。首先判断是否已经登录,如果登录后再判断当前登录人是否具有当前路由地址的访问权限

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate {

  /**
   * ctor
   * @param router 路由
   */
  constructor(private router: Router) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

    // 判断是否有 token 信息
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    // 判断是否可以访问当前连接
    let url: string = state.url;
    if (token === 'admin' && url === '/crisis-center') {
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }
}

之后我们就可以在 app-routing.module.ts 文件中引入 AuthGuard 类,针对需要保护的路由进行路由守卫的配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

// 引入组件
import { CrisisListComponent } from './crisis-list/crisis-list.component';

// 引入路由守卫
import { AuthGuard } from './auth/auth.guard';

const routes: Routes = [
  {
    path: 'crisis-center',
    component: CrisisListComponent,
    canActivate: [AuthGuard], // 添加针对当前路由的 canActivate 路由守卫
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule { }
4.2.2、CanActivateChild:针对子路由的认证授权

与继承 CanActivate 接口进行路由守卫的方式相似,针对子路由的认证授权可以通过继承 CanActivateChild 接口来实现,因为授权的逻辑很相似,这里通过多重继承的方式,扩展 AuthGuard 的功能,从而达到同时针对路由和子路由的路由守卫

改造下原先 canActivate 方法的实现,将认证逻辑修改为用户的 token 信息中包含 admin 即可访问 crisis-center 页面,在针对子路由进行认证授权的 canActivateChild 方法中,通过判断 token 信息是否为 admin-master 模拟完成对于子路由的访问认证

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router, CanActivateChild } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanActivateChild {

  /**
   * ctor
   * @param router 路由
   */
  constructor(private router: Router) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

    // 判断是否有 token 信息
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    // 判断是否可以访问当前连接
    let url: string = state.url;
    if (token.indexOf('admin') !== -1 && url.indexOf('/crisis-center') !== -1) {
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }

  canActivateChild(
    childRoute: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    return token === 'admin-master';
  }
}

通过 Angular CLI 新增一个 crisis-detail 组件,作为 crisis-list 的子组件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ng g component crisis-detail

接下来在 crisis-list 中添加 router-outlet 标签,用来定义子路由的渲染出口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<h2>危机中心</h2>

<ul class="crises">
  <li *ngFor="let crisis of crisisList">
    <a [routerLink]="[crisis.id]">
      <span class="badge">{{ crisis.id }}</span>{{ crisis.name }}
    </a>
  </li>
</ul>

<!-- 定义子路由的渲染出口 -->
<router-outlet></router-outlet>

在针对子路由的认证授权配置时,我们可以选择针对每个子路由添加 canActivateChild 属性,也可以定义一个空地址的子路由,将所有归属于 crisis-list 的子路由作为这个空路由的子路由,通过针对这个空路径添加 canActivateChild 属性,从而实现将守护规则应用到所有的子路由上

这里其实相当于将原先两级的路由模式(父:crisis-list,子:crisis-detail)改成了三级(父:crisis-list,子:' '(空路径),孙:crisis-detail)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

// 引入组件
import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';

// 引入路由守卫
import { AuthGuard } from './auth/auth.guard';

const routes: Routes = [
  {
    path: 'crisis-center',
    component: CrisisListComponent,
    canActivate: [AuthGuard], // 添加针对当前路由的 canActivate 路由守卫
    children: [{
      path: '',
      canActivateChild: [AuthGuard], // 添加针对子路由的 canActivate 路由守卫
      children: [{
        path: 'detail',
        component: CrisisDetailComponent
      }]
    }]
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule { }
4.2.3、CanDeactivate:处理用户未提交的修改

当进行表单填报之类的操作时,因为会涉及到一个提交的动作,当用户没有点击保存按钮就离开时,最好能暂停,对用户进行一个友好性的提示,由用户选择后续的操作

创建一个路由守卫,继承于 CanDeactivate 接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ng g guard hero-list/guards/hero-can-deactivate

与上面的 CanActivate、CanActivateChild 路由守卫的使用方式不同,对于 CanDeactivate 守卫来说,我们需要将参数中的 unknown 替换成我们实际需要进行路由守卫的组件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { Injectable } from '@angular/core';
import { CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree } from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class HeroCanDeactivateGuard implements CanDeactivate<unknown> {
  canDeactivate(
    component: unknown,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState?: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return true;
  }
  
}

例如,这里针对的是 HeroListComponent 这个组件,因此我们需要将泛型的参数 unknown 改为 HeroListComponent,通过 component 参数,就可以获得需要进行路由守卫的组件的相关信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { Injectable } from '@angular/core';
import {
  CanDeactivate,
  ActivatedRouteSnapshot,
  RouterStateSnapshot,
  UrlTree,
} from '@angular/router';
import { Observable } from 'rxjs';

// 引入需要进行路由守卫的组件
import { HeroListComponent } from '../hero-list.component';

@Injectable({
  providedIn: 'root',
})
export class HeroCanDeactivateGuard
  implements CanDeactivate<HeroListComponent> {
  canDeactivate(
    component: HeroListComponent,
    currentRoute: ActivatedRouteSnapshot,
    currentState: RouterStateSnapshot,
    nextState?: RouterStateSnapshot
  ):
    | Observable<boolean | UrlTree>
    | Promise<boolean | UrlTree>
    | boolean
    | UrlTree {

    // 判断是否修改了原始数据
    //
    const data = component.hero;
    if (data === undefined) {
      return true;
    }
    const origin = component.heroList.find(hero => hero.id === data.id);
    if (data.name === origin.name) {
      return true;
    }

    return window.confirm('内容未提交,确认离开?');
  }
}

这里模拟判断用户有没有修改原始的数据,当用户修改了数据并移动到别的页面时,触发路由守卫,提示用户是否保存后再离开当前页面

4.3、异步路由
4.3.1、惰性加载

当应用逐渐扩大,使用现有的加载方式会造成应用在第一次访问时就加载了全部的组件,从而导致系统首次渲染过慢。因此这里可以使用惰性加载的方式在请求具体的模块时才加载对应的组件

惰性加载只针对于特性模块(NgModule),因此为了使用惰性加载这个功能点,我们需要将系统按照功能划分,拆分出一个个独立的模块

首先通过 Angular CLI 创建一个危机中心模块(crisis 模块)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
-- 查看创建模块的相关参数
ng g module --help

-- 创建危机中心模块(自动在 app.moudule.ts 中引入新创建的 CrisisModule、添加当前模块的路由配置)
ng g module crisis --module app --routing

将 crisis-list、crisis-detail 组件全部移动到 crisis 模块下面,并在 CrisisModule 中添加对于 crisis-list、crisis-detail 组件的声明,同时将原来在 app.module.ts 中声明的组件代码移除

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { CrisisRoutingModule } from './crisis-routing.module';

import { FormsModule } from '@angular/forms';

// 引入模块中使用到的组件
import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';


@NgModule({
  declarations: [
    CrisisListComponent,
    CrisisDetailComponent
  ],
  imports: [
    CommonModule,
    FormsModule,
    CrisisRoutingModule
  ]
})
export class CrisisModule { }

同样的,将当前模块的路由配置移动到专门的路由配置文件 crisis-routing.module.ts 中,并将 app-routing.module.ts 中相关的路由配置删除

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

// 引入组件
import { CrisisListComponent } from './crisis-list/crisis-list.component';
import { CrisisDetailComponent } from './crisis-detail/crisis-detail.component';

// 引入路由守卫
import { AuthGuard } from '../auth/auth.guard';

const routes: Routes = [{
  path: '',
  component: CrisisListComponent,
  canActivate: [AuthGuard], // 添加针对当前路由的 canActivate 路由守卫
  children: [{
    path: '',
    canActivateChild: [AuthGuard], // 添加针对子路由的 canActivate 路由守卫
    children: [{
      path: 'detail',
      component: CrisisDetailComponent
    }]
  }]
}];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class CrisisRoutingModule { }

重新运行项目,如果你在创建模块的命令中设置了自动引入当前模块到 app.module.ts 文件中,大概率会遇到下面的问题

这里的问题与配置通配路由需要放到最后的原因相似,因为脚手架在帮我们将创建的模块导入到 app.module.ts 中时,是添加到整个数组的最后,同时因为我们已经将 crisis 模块的路由配置移动到专门的 crisis-routing.module.ts 中了,框架在进行路由匹配时会预先匹配上 app-routing.module.ts 中设置的通配路由,从而导致无法找到实际应该对应的组件,因此这里我们需要将 AppRoutingModule 放到声明的最后

当问题解决后,就可以针对 crisis 模块设置惰性加载

在配置惰性路由时,我们需要以一种类似于子路由的方式进行配置,通过路由的 loadChildren 属性来加载对应的模块,而不是具体的组件,修改后的 AppRoutingModule 代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { HeroCanDeactivateGuard } from './hero-list/guards/hero-can-deactivate.guard';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: 'crisis-center',
    loadChildren: () => import('./crisis/crisis.module').then(m => m.CrisisModule)
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { enableTracing: true })],
  exports: [RouterModule],
})
export class AppRoutingModule { }

当导航到这个 /crisis-center 路由时,框架会通过 loadChildren 字符串来动态加载 CrisisModule,然后把 CrisisModule 添加到当前的路由配置中,而惰性加载和重新配置工作只会发生一次,也就是在该路由首次被请求时执行,在后续请求时,该模块和路由都是立即可用的

4.3.2、CanLoad:杜绝未通过认证授权的组件加载

在上面的代码中,对于 CrisisModule 模块我们已经使用 CanActivate、CanActivateChild 路由守卫来进行路由的认证授权,但是当我们并没有权限访问该路由的权限,却依然点击了链接时,此时框架路由仍会加载该模块。为了杜绝这种授权未通过仍加载模块的问题发生,这里需要使用到 CanLoad 守卫

因为这里的判断逻辑与认证授权的逻辑相同,因此在 AuthGuard 中,继承 CanLoad 接口即可,修改后的 AuthGuard 代码如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { Injectable } from '@angular/core';
import {
  CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree, Router, CanActivateChild, CanLoad, Route, UrlSegment
} from '@angular/router';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {

  /**
   * ctor
   * @param router 路由
   */
  constructor(private router: Router) { }


  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

    // 判断是否有 token 信息
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    // 判断是否可以访问当前连接
    let url: string = state.url;
    if (token.indexOf('admin') !== -1 && url.indexOf('/crisis-center') !== -1) {
      return true;
    }

    this.router.navigate(['/login']);
    return false;
  }

  canActivateChild(
    childRoute: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): boolean | UrlTree | Observable<boolean | UrlTree> | Promise<boolean | UrlTree> {
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    return token === 'admin-master';
  }

  canLoad(route: Route, segments: UrlSegment[]): boolean | Observable<boolean> | Promise<boolean> {
    let token = localStorage.getItem('auth-token') || '';
    if (token === '') {
      this.router.navigate(['/login']);
      return false;
    }

    let url = `/${route.path}`;

    if (token.indexOf('admin') !== -1 && url.indexOf('/crisis-center') !== -1) {
      return true;
    }
  }
}

同样的,针对路由守卫的实现完成后,将需要使用到的路由守卫添加到 crisis-center 路由的 canLoad 数组中即可实现授权认证不通过时不加载模块

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import { HeroCanDeactivateGuard } from './hero-list/guards/hero-can-deactivate.guard';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
  {
    path: 'crisis-center',
    loadChildren: () => import('./crisis/crisis.module').then(m => m.CrisisModule)
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes, { enableTracing: true })],
  exports: [RouterModule],
})
export class AppRoutingModule { }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-06-03 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
实时音视频 TRTC 常见问题汇总---WebRTC篇
TRTC Web SDK 对浏览器的详细支持度,您可以查看 TRTC Web SDK 对浏览器支持情况。
腾讯视频云-Zachary
2019/11/15
23.4K3
实时音视频 TRTC 常见问题汇总---WebRTC篇
音视频之音频相关概念介绍
在从事音视频的音频开发中,难免会遇到一些问题,比如声音异常,回音等问题,这时候有比较牢固的概念基础会对分析这些问题很有帮助。本篇就介绍下音频相关的概念
一只小虾米
2022/10/25
1.4K0
音视频之音频相关概念介绍
TRTC上下行无声怎么处理
打开监控仪表盘,输入 sdkappid 和 roomid,并切换到问题用户的通话详情页面,之后再切换到音频详情页卡。如果音频发送码率不正常(持续小于16kbps),则为上行无声;如果音频接受码率不正常(持续小于16kbps),则为下行无声。
TRTC小百科
2021/10/11
2.8K0
腾讯会议如何保证语音质量?音频信号处理中有这些秘籍!
导读 | 腾讯会议在去年年底推出,集结腾讯在AI、云计算、安全等方面的能力,全方位满足不同场景下的会议需求,在短短两个月内就突破千万日活大关。面对多样且复杂的场景,比如开会环境嘈杂、同一地点多设备接入、房间声学参数不理想等,腾讯会议如何通过对音频信号的处理持续保障高品质通话,提升沟通效率?本文是腾讯多媒体实验室音频技术专家李岳鹏在「腾讯技术开放日·云视频会议专场」的分享整理。 点击视频,查看直播回放 一、TRAE技术降噪增益揭秘 先简单讲一下VOIP中语音数据实时传输路径图,我们可以看到远端的数据通过
腾讯多媒体实验室
2020/04/01
7.8K1
音视频技术基础(六)-- 3A处理
前面我们有学到,音视频数据的处理过程有个预处理过程,也就是在音视频数据采集完成之后的一步,音频的预处理就是用的3A处理,3A即AEC、ANS、AGC。当音频同时存在上下行,AEC必不可少。
黑眼圈云豆
2020/07/12
10K1
微信小程序使用TRTC
在使用之前我们需要了解 <live-player> 和 <live-pusher> 微信小程序原生组件,因为小程序TRTC组件标签 <trtc-room> 是基于这两个标签实现的组件,所以在运行调试时开发工具是不支持的,只能在真机上运行。
yuliang
2021/03/10
3K0
音视频知识图谱 2022.06
前些时间,我在知识星球上创建了一个音视频技术社群:关键帧的音视频开发圈,在这里群友们会一起做一些打卡任务。比如:周期性地整理音视频相关的面试题,汇集一份音视频面试题集锦,你可以看看这个合集:音视频面试题集锦。再比如:循序渐进地归纳总结音视频技术知识,绘制一幅音视频知识图谱,你可以看看这个合集:音视频知识图谱。
关键帧
2022/11/29
6820
音视频知识图谱 2022.06
云视频会议背后的语音核心技术揭秘:如何进行语音质量评估?
导读 | 自疫情发生以来,腾讯会议每天都在进行资源扩容,日均扩容主机接近1.5万台,用户活跃度攀升。在如此高并发流量的冲击下,腾讯会议如何保证语音通信清晰流畅?如何对语音质量进行评估?在【腾讯技术开放日·云视频会议专场】中,腾讯多媒体实验室音频技术专家易高雄针对语音质量评估进行了分享。 点击视频,查看直播回放 一、语音质量界定     音频和语音是电声学下面两个不同的学科分支,属于两个不同的应用,两者在应用目的、使用场景、行业和用户认知统一度三方面存在差异,所以对于语音质量测试来说,首先要界定一下评估对象
腾讯多媒体实验室
2020/04/13
3K0
实时音视频助力在线教育风口
各位朋友大家好,今天主要是来分享关于实时音视频与教育的结合。本来最开始的标题是“TRTC与在线教育的那些事儿”,但考虑大家都是做技术的,所以改为“实时视频助力在线教育的新风口”,能力有限,如果有错误与问题,还请多多指教,欢迎一起交流学习。
LiveVideoStack
2020/11/12
1.5K0
实时音视频助力在线教育风口
你问我答 | 实时音视频TRTC(2021年5月-7月)
实时音视频TRTC 你问我答 第1季 本期共解答10个问题 Q1:移动端(Andriod/iOS)支持哪几种系统音量模式? 支持2种系统音量类型,即通话音量类型和媒体音量类型: 通话音量,手机专门为通话场景设计的音量类型,使用手机自带的回声抵消功能,音质相比媒体音量类型较差, 无法通过音量按键将音量调成零,但是支持蓝牙耳机上的麦克风。 媒体音量,手机专门为音乐场景设计的音量类型,音质相比于通话音量类型要好,通过通过音量按键可以将音量调成零。使用媒体音量类型时,如果要开启回声抵消(AEC
腾讯云音视频
2021/08/30
1.4K0
直播新玩法背后的音视频技术演进
近年来,直播改变了许多行业模式,其形态在不断的演进中也逐渐丰富起来。直播在字节跳动中衍生出了KTV歌房、直播答题、互动游戏、电商拍卖及企业直播等不同场景。本次分享我们邀请到火山引擎视频云音视频直播客户端研发负责人——徐鸿,向大家介绍直播场景中沉淀下的优秀架构能力和技术能力。
LiveVideoStack
2021/12/27
1.5K0
直播新玩法背后的音视频技术演进
音视频基础能力之 Android 音频篇 (四):音频路由
涉及硬件的音视频能力,比如采集、渲染、硬件编码、硬件解码,通常是与客户端操作系统强相关的,就算是跨平台的多媒体框架也必须使用平台原生语言的模块来支持这些功能。本系列文章将详细讲述移动端音视频的采集、渲染、硬件编码、硬件解码这些涉及硬件的能力该如何实现。
声知视界
2024/12/23
8050
音视频基础能力之 Android 音频篇 (四):音频路由
创新架构扫清难题,TRTC实时合唱解决方案让你在家Get千人大合唱的快乐!
同时,全民K歌还持续打造明星大合唱玩法,与吴克群、张远、陈卓璇等超多实力歌手合作,邀请他们空降歌房和K歌粉丝实时互动。有实力的粉丝可以参与选拔,赢取与明星1v1对唱的机会。普通歌迷朋友也可以加入”明星空降大合唱“,歌手作为领唱,歌迷点击”加入合唱“,便可与明星同框合唱,无需抢票去现场,在家就能分分钟Get演唱会全场合唱的快乐,获得堪比演唱会现场的沉浸式体验。
腾讯云音视频
2024/04/30
5010
创新架构扫清难题,TRTC实时合唱解决方案让你在家Get千人大合唱的快乐!
解决方案 | “金三银四”盛装出席,TRTC视频面试方案助你抢到心动offer!
去年的招聘季,“金三银四”双双缺席,疫情之下的求职,非常艰难,存在着打工人返乡之后获取不到招聘信息、应届毕业生对行业了解较少、企业雇主无法深入面试筛选合适的人才等问题。在疫情这个大环境的影响下,线上视频招聘面试犹如“雪中送炭”一样。虽然国内疫情基本已经过去,但是越来越多的企业HR和求职者更热衷于视频面试这种跨越时空的方式。 我们常见的线上招聘场景有两种: 1、线下面试线上化 从具体操作看,招聘者与候选人达成面试意向后,可预约面试时间或直接发起视频面试邀请,候选人接受视频面试并如期进入线上面试房间,双
腾讯云音视频
2021/04/15
5830
iOS 音视频接入 - 初识TRTC
在上一篇文章中我们对音视频有了最基础的认识,下面就来了解下第三方提供的功能强大的实时音视频SDK-TRTC。
小明同学接音视频
2020/10/09
3.1K0
iOS 音视频接入 - 初识TRTC
如何做好游戏内实时语音体验
本文即针对移动游戏环境下实时语音所面对的挑战,介绍一些语音预处理、流媒体协议等通用的解决方案。
腾讯游戏云
2018/02/28
13.7K4
如何做好游戏内实时语音体验
微信小程序TRTC使用custom自定义面板(实现篇)
本文主要是使用 custom 面板实现直播互动,上下麦操作。如有疑问可参考 微信小程序TRTC使用custom自定义面板(理解篇)。本文只是简单演示如何实现主播与观众进行连麦互动,在实际中,通常是有主播端发起与粉丝进行直播互动,通过粉丝来接受,进行连麦。发送这种消息可以使用IM(即时通讯)完成。
yuliang
2021/03/16
1.4K0
实时音视频 TRTC 常见问题汇总---咨询问题篇
TRTC 是腾讯云基于 QQ 十多年来在音视频通话技术上积累,结合腾讯浏览服务 TBS WebRTC 能力与腾讯实时音视频 SDK ,为客户提供多平台互通高品质可定制化的 实时音视频互通服务 解决方案。 (1)您可以通过“crtl+F”(win)、“command+F”(mac)搜索关键字。 (2)若没有您想要的问答,欢迎在评论区提问、留言和交流,笔者会定期解答疑惑。 (3)最新产品动态与变更以官网文档为准。
TRTC小百科
2021/09/16
9.2K2
IEEE ASRU 2023录用论文解读 | 打造极致听觉体验,腾讯云MPS音频处理能力及降噪算法原理
近期,语音与语言处理领域旗舰会议IEEE ASRU 2023论文入选结果公布。腾讯云媒体处理(MPS)在语音增强降噪方向的创新成果再获业界认可,《Magnitude-and-phase-aware Speech Enhancement with Parallel Sequence Modeling》(简称MPCRN)和《VSANet: Real-time Speech Enhancement Based on Voice Activity Detection and Causal Spatial Attention》(简称VSANet)两篇论文被IEEE ASRU 2023录用。本文将结合论文内容,与大家分享腾讯云媒体处理(MPS)在音频处理方面的最新能力、相关技术方案以及算法原理。
腾讯云音视频
2023/11/05
7970
IEEE ASRU 2023录用论文解读 | 打造极致听觉体验,腾讯云MPS音频处理能力及降噪算法原理
实时音视频 TRTC 常见问题汇总---集成接入篇
TRTC 的日志默认压缩加密,后缀为 .xlog。日志是否加密是可以通过 setLogCompressEnabled 来控制,生成的文件名里面含 C(compressed) 的就是加密压缩的,含 R(raw) 的就是明文的。
腾讯视频云-Zachary
2019/11/01
14.7K1
实时音视频 TRTC 常见问题汇总---集成接入篇
推荐阅读
相关推荐
实时音视频 TRTC 常见问题汇总---WebRTC篇
更多 >
交个朋友
加入前端学习入门群
前端基础系统教学 经验分享避坑指南
加入腾讯云技术交流站
前端技术前沿探索 云开发实战案例分享
加入云开发企业交流群
企业云开发实战交流 探讨技术架构优化
换一批
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档