as

Settings
Sign out
Notifications
Alexa
亚马逊应用商店
AWS
文档
Support
Contact Us
My Cases
新手入门
设计和开发
应用发布
参考
支持

使用Hls.js播放器播放自适应内容

使用Hls.js播放器播放自适应内容

以下步骤介绍如何将Hls.js播放器用于MSE模式,以播放自适应流媒体内容。

尽管亚马逊提供的Hls.js播放器补丁针对的是特定版本的播放器,但您可以将它们移植到您想使用的任何版本的Hls.js播放器上。亚马逊没有规定您必须使用的任何特定Hls.js播放器版本。您可以决定哪个版本的Hls.js播放器最适合您的要求。有关Hls.js播放器处理您内容的能力的问题,请洽询开源社区。

有关Hls.js播放器及其支持的不同配置的更多详细信息,请参阅Hls.js播放器

先决条件

在开始修改代码以在Hls.js播放器上播放自适应内容之前,请先满足以下先决条件以设置您的应用和播放器:

  • 将您的应用设置成使用W3C媒体播放器。有关更多信息,请参阅媒体播放器设置

配置适用于Vega的Hls.js播放器

  1. 将适用于Vega的Hls.js播放器下载到已知位置。

    Vega支持以下Hls.js版本:

    • v1.5.11-r1.5 - 更新了polyfill以支持Headless JS播放。将导入路径从@amazon-devices/react-native-w3cmedia改为@amazon-devices/react-native-w3cmedia/dist/headless
  2. 展开Hls.js播放器程序包。

    tar -xzf hls-rel-v<x.y.z>-r<a.b>.tar.gz

    例如:

    tar -xzf hls-rel-v1.5.11-r1.5.tar.gz

  3. 导航到/hls-rel/scripts目录。
  4. 运行setup.sh帮助脚本。setup.sh脚本执行构建,生成一个名为hls.js的目录。
    • 从生成的hls.js目录中,将hls-rel/src/*目录中的内容复制到<应用根目录>/src/*
    • 从生成的hls.js目录中,将dist目录复制到<应用根目录>/src/hlsjsplayer/dist

播放自适应内容

完成以下步骤,在安装Video组件后加载Hls.js播放器。

使用Hls.js播放器播放自适应内容

  • 打开您的src/App.tsx并用以下代码替换内容。

    已复制到剪贴板。

    /*
    * 版权所有 (c) 2024 Amazon.com, Inc.或其关联公司。 保留所有权利。
    *
    * 专有/机密信息。 相关使用受许可条款的约束。
    */
    
    import * as React from 'react';
    import {useRef, useState, useEffect} from 'react';
    import {
      Platform,
      useWindowDimensions,
      View,
      StyleSheet,
      TouchableOpacity,
      Text,
    } from 'react-native';
    
    import {
      VideoPlayer,
      VegaVideoSurfaceView,
      VegaCaptionsView,
    } from '@amazon-devices/react-native-w3cmedia';
    import { HlsJsPlayer } from './hlsjsplayer/HlsJsPlayer';
    
    // 如果应用需要手动在视频上调用播放API,则设置为false
    const AUTOPLAY = true;
    
    const DEFAULT_ABR_WIDTH: number = Platform.isTV ? 3840 : 1919;
    const DEFAULT_ABR_HEIGHT: number = Platform.isTV ? 2160 : 1079;
    
    const content = [
      {
        secure: 'false', // true: 使用安全视频缓冲区。false: 使用不安全的视频缓冲区。
        uri: 'https://storage.googleapis.com/shaka-demo-assets/bbb-dark-truths-hls/hls.m3u8',
        drm_scheme: '', // com.microsoft.playready, com.widevine.alpha
        drm_license_uri: '', // DRM许可证获取服务器URL:仅当内容受DRM保护时才需要
      },
    ];
    
    export const App = () => {
      const player = useRef<any>(null);
      const videoPlayer = useRef<VideoPlayer | null>(null);
      const timeoutHandler = useRef<ReturnType<typeof setTimeout> | null>(null);
      const [buttonPress, setButtonPress] = useState(false);
      const [nextContent, setNextContent] = useState({index: 0}); // { index: number }
      //跟踪nextContent状态以进行重新呈现
      const nextContentRef = useRef<number>(0);
      //以全屏分辨率呈现
      const {width: deviceWidth, height: deviceHeight} = useWindowDimensions();
    
      useEffect(() => {
        if (nextContent.index !== nextContentRef.current) {
          nextContentRef.current = nextContent.index;
          // 强制重新渲染<Video>组件。
          initializeVideoPlayer();
          setNextContent((prev) => {
            return {...prev};
          });
        }
      }, [nextContent]);
    
      useEffect(() => {
        console.log('app:启动AppPreBuffering v13.0');
        initializeVideoPlayer();
      }, []);
    
      const onEnded = async () => {
        console.log('app:已收到onEnded');
        player.current.unload();
        player.current = null;
        await videoPlayer.current?.deinitialize();
        removeEventListeners();
        onVideoUnMounted();
        setNextContent({index: (nextContent.index + 1) % content.length});
      };
    
      const onError = () => {
        console.log(`app: AppPreBuffering:调用了错误事件侦听器`);
      };
    
      const setUpEventListeners = (): void => {
        console.log('app:设置事件侦听器');
        videoPlayer.current?.addEventListener('ended', onEnded);
        videoPlayer.current?.addEventListener('error', onError);
      };
    
      const removeEventListeners = (): void => {
        console.log('app:删除事件侦听器');
        videoPlayer.current?.removeEventListener('ended', onEnded);
        videoPlayer.current?.removeEventListener('error', onError);
      };
    
      const initializeVideoPlayer = async () => {
        console.log('app:调用initializeVideoPlayer');
        videoPlayer.current = new VideoPlayer();
        // @ts-ignore
        global.gmedia = videoPlayer.current;
        await videoPlayer.current.initialize();
        setUpEventListeners();
        videoPlayer.current!.autoplay = false;
        initializeHls();
      };
    
      const onSurfaceViewCreated = (surfaceHandle: string): void => {
        console.log('app:已创建表面');
        videoPlayer.current?.setSurfaceHandle(surfaceHandle);
        videoPlayer.current?.play();
      };
    
      const onSurfaceViewDestroyed = (surfaceHandle: string): void => {
        videoPlayer.current?.clearSurfaceHandle(surfaceHandle);
      };
    
      const onCaptionViewCreated = (captionsHandle: string): void => {
        console.log('app:已创建字幕视图');
        videoPlayer.current?.setCaptionViewHandle(captionsHandle);
      };
    
      const initializeHls = () => {
        console.log('app: in initializePlayer() index = ', nextContent.index);
        if (videoPlayer.current !== null) {
          player.current = new HlsJsPlayer(videoPlayer.current);
        }
        if (player.current !== null) {
          player.current.load(content[nextContent.index], AUTOPLAY);
        }
      };
    
      const onVideoUnMounted = (): void => {
        console.log('app: in onVideoUnMounted');
        // @ts-ignore
        global.gmedia = null;
        videoPlayer.current = null;
      };
    
      if (!buttonPress) {
        return (
          <View style={styles.container}>
            <TouchableOpacity
              style={styles.button}
              onPress={() => {
                setButtonPress(true);
              }}
              hasTVPreferredFocus={true}
              activeOpacity={1}>
              <Text style={styles.buttonLabel}> Press to Play Video </Text>
            </TouchableOpacity>
          </View>
        );
      } else {
        return nextContent.index === nextContentRef.current ? (
          <View style={styles.videoContainer}>
            <VegaVideoSurfaceView
              style={styles.surfaceView}
              onSurfaceViewCreated={onSurfaceViewCreated}
              onSurfaceViewDestroyed={onSurfaceViewDestroyed}
            />
            <VegaCaptionsView
              onCaptionViewCreated={onCaptionViewCreated}
              style={styles.captionView}
            />
          </View>
        ) : (
          <View style={styles.videoContainer}></View>
        );
      }
    };
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        flexDirection: 'column',
        backgroundColor: '#283593',
        justifyContent: 'center',
        alignItems: 'center',
      },
      button: {
        alignItems: 'center',
        backgroundColor: '#303030',
        borderColor: 'navy',
        borderRadius: 10,
        borderWidth: 1,
        paddingVertical: 12,
        paddingHorizontal: 32,
      },
      buttonLabel: {
        color: 'white',
        fontSize: 22,
        fontFamily: 'Amazon Ember',
      },
      videoContainer: {
        backgroundColor: 'white',
        alignItems: 'stretch',
      },
      surfaceView: {
        zIndex: 0,
      },
      captionView: {
        width: '100%',
        height: '100%',
        top: 0,
        left: 0,
        position: 'absolute',
        backgroundColor: 'transparent',
        flexDirection: 'column',
        alignItems: 'center',
        zIndex: 2,
      }
    });
    
  • 使用Vega SDK来构建应用,在设备或模拟器上运行它并收集日志。有关在模拟器上构建和运行应用的更多详细信息,请参阅创建Vega应用Vega虚拟设备

手动集成Hls.js播放器

  1. https://github.com/video-dev/hls.js克隆Hls.js程序包。

    已复制到剪贴板。

    cd <根目录>
    git clone https://github.com/video-dev/hls.js.git
    
  2. 将基于v1.5.11的git分支签出到名为v1.5.11-kepler的本地分支。

    已复制到剪贴板。

    cd hls.js
    git checkout -b amz_1.5.11 v1.5.11
    
  3. 将Vega Hls.js播放器程序包下载到已知位置,您将在此解压该文件。
  4. 展开文件。

    已复制到剪贴板。

    tar -xzf hls-rel-v[x.y.z]-r[x.y].tar.gz
    
  5. 应用Hls.js补丁:

    已复制到剪贴板。

     git apply hls-rel/hls-patch/*.patch -3
    
  6. 通过运行npm install安装Hls.js依赖项:

    已复制到剪贴板。

    npm install
    
  7. 通过运行npm run build来构建Hls.js播放器

    已复制到剪贴板。

     npm run build  
    

    如果您收到错误消息,指出内部版本无法解析base-64和xmldom节点模块,请运行以下命令进行安装。

    已复制到剪贴板。

    npm install --save base-64   
    

    已复制到剪贴板。

    bash      npm install --save xmldom


Last updated: 2025年9月30日