HLS视频加密及本地播放 - &大飞

时间:2024-02-29 18:46:22

HLS视频加密及本地播放

一、视频加密

将视频从MP4文件切片成多个ts文件,并使用AES-128对每一片视频进行加密,最后生成m3u8文件
视频加密参考:https://www.cnblogs.com/codeAB/p/9184266.html

1、生成公有key

openssl rand  16 > encrypt.key

2、生成私有key(16进制)

openssl rand -hex 16

3、按照下面格式新建一个encrypt.keyinfo的文件

Key URI  # enc.key的路径,使用http形式
Path to key file  # enc.key文件
Private key  #  上面生成的16进制的私有key

举个例子

http://192.168.1.111:8090/encrypt.key
/home/Admin/encrypt.key
8b4c39c498949536f8d2af1f6fec7d39

4、使用ffmpeg开始分片并加密

#           源视频文件 |单片时长(s) |             key信息文件           | 设置为点播,切片不会变   |                 分片名字          |  m3u8名字
ffmpeg -y -i test.mp4 -hls_time 4 -hls_key_info_file encrypt.keyinfo -hls_playlist_type vod -hls_segment_filename "test_%d.ts" index.m3u8

二、视频播放

对于Android手机是不能直接播放的,必须要搭建服务器,使用Ubuntu搭建服务器请参考网络直播/点播服务器搭建
这里主要讲解如何在Android手机上搭建m3u8视频服务器,NanoHTTPD可以轻松搭建WebServer。
本地播放参考https://gitee.com/2021/LPlayer

1、继承NanoHTTPD实现M3u8Server

public class M3u8Server extends NanoHTTPD {
    private static String TAG = "M3U8Server";
    private static NanoHTTPD server;
    public static final int PORT = 8999;

    /**
     * 启动服务
     */
    public static void execute() {
        if (server != null) return;
        try {
            server = M3u8Server.class.newInstance();
            server.start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
        } catch (IOException e) {
            Log.e(TAG, "Start m3u8 server fail:", e);
            System.exit(-1);
        } catch (Exception e) {
            Log.e(TAG, "Start m3u8 server fail:", e);
            System.exit(-1);
        }

        try {
            System.in.read();
        } catch (Throwable ignored) {
        }
    }

    /**
     * 关闭服务
     */
    public static void finish() {
        if (server != null) {
            server.stop();
            server = null;
        }
    }

    public M3u8Server() {
        super(PORT);
    }

    @Override
    public Response serve(IHTTPSession session) {
        String url = String.valueOf(session.getUri());
        Log.d(TAG, "Request URL:" + url);
        File file = new File(url);

        if (file.exists()) {
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(file);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/html", "Not found:" + url);
            }
            long length = file.length();
            // ts文件
            String mimeType = "video/mpeg";
            if (url.contains(".m3u8")) {
                // m3u8文件
                mimeType = "video/x-mpegURL";
            }
            return newChunkedResponse(Response.Status.OK, mimeType, fis);
        } else {
            return newFixedLengthResponse(Response.Status.NOT_FOUND, "text/html", "Not found:" + url);
        }
    }
}

2、使用

开启服务

M3u8Server.execute();

关闭服务

M3u8Server.finish();

服务器请求链接说明

//                                      端口 |    m3u8文件路径
String.format("http://127.0.0.1:%d/%s", 8999, "/storage/emulated/0/Movies/crypt/index.m3u8")

最后提供一个单java文件的NanoHTTPD,简单,高效,赞一个