ChinaFFmpeg

 找回密码
 立即注册

QQ登录

只需一步,快速开始

123
返回列表 发新帖
楼主: 孙悟空

[Linux] code实现从ts切片成m3u8/HLS

[复制链接]
发表于 2015-6-18 19:33:36 | 显示全部楼层
孙悟空 发表于 2015-6-18 17:47
现在感觉屌爆了,是吧

还是会有问题,感觉这个hls的muxer不是很好,我如果要live跟record两个线程一块用好像不行,会报non monotonical increasing dts的问题,我回头看看segment的muxer好不好用。
回复 支持 反对

使用道具 举报

发表于 2015-6-23 19:49:56 | 显示全部楼层
孙悟空 发表于 2015-6-18 17:47
现在感觉屌爆了,是吧

大师兄,想再跟请请教一下,你的这个demo我单独起了一个线程,起了一次没有问题,工作正常,但是起第二次的时候就会有dts monotonical的问题,请教一下这个咋回事。我明天把代码贴上来。
回复 支持 反对

使用道具 举报

发表于 2015-6-24 09:21:25 | 显示全部楼层
本帖最后由 derekzhuo 于 2015-6-24 09:29 编辑

这个代码第一次工作正常,但是第二次起来就会有这个问题;
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 7220696620 >= 7220505820
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 7220696620 >= 7220509420
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 7220696620 >= 7220513020
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 7220696620 >= 7220516620
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 7220696620 >= 7220520220
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 0: 7220696620 >= 7220523820
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 7220673201 >= 7220498241
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 7220673201 >= 7220500401
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 7220673201 >= 7220502561
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 7220673201 >= 7220504721
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 7220673201 >= 7220506881
Muxing Error, Discarding One Packet
[hls @ 0xb8774ec0] Application provided invalid, non monotonically increasing dts to muxer in stream 1: 7220673201 >= 7220509041

[C] 纯文本查看 复制代码
#include <stdlib.h>
代码如下:
#include <stdio.h>
#include <string.h>
#include <string.h>
#include <sys/types.h>
#include <signal.h>
#include <netinet/in.h>
#include <net/if.h>
#include <net/if_arp.h>
#include <arpa/inet.h>
#include <time.h>
#include <dirent.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#include <sys/time.h>

#include <pthread.h>
#include <api/libdvbrec/libprovider.h>
#include <api/libdvbrec/libhlssegmenter.h>

/*********************************************************************************************
*   Function Declaration(All Static)                                                                                                                                 *
*********************************************************************************************/

static int live_hls_segmenter_fill_iobuffer(void *opaque, uint8_t *buf, int buf_size);
static int record_hls_segmenter_fill_iobuffer(void *opaque, uint8_t *buf, int buf_size);


static int hls_segmenter_get_ip(char *ipaddr);
static int hls_segmenter_get_sys_time(char* localdate);
static int hls_segmenter_mkdir(const char* path);
static int hls_segmenter_set_url(char *pre_url);


static void* live_hls_segmenter_thread();
static void* record_hls_segmenter_thread();


static int live_hls_segmenter_start(struct dvbrec_stream_info* stream_info);
static int live_hls_segmenter_stop();


static int record_hls_segmenter_start(struct dvbrec_stream_info* stream_info);
static int record_hls_segmenter_stop();


static int record_set_index_name(char* index_filename);


static unsigned long int live_readdata_from_ring_buffer(unsigned char* buf, int size);
static unsigned long int record_readdata_from_ring_buffer(unsigned char* buf, int size);

/*********************************************************************************************
*   Function Definition                                                                                                                                 *
*********************************************************************************************/
static int hls_segmenter_set_url(char *pre_url)
{
    char* ip_addr[16] = {0};
    hls_segmenter_get_ip(ip_addr);
    memset(pre_url, 0x00, sizeof(pre_url));
    sprintf(pre_url, "http://");
    strcat(pre_url, ip_addr);
    strcat(pre_url, "/");    
    fprintf(stdout, "url = %s \n", pre_url);
    return 0;
}

static int hls_segmenter_mkdir(const char* path)
{
    DIR *dp;
    if ((dp = opendir(path)) == NULL)
    {
        //folder doesn't exist
        if(mkdir(path, S_IRWXU) == -1) {
            fprintf(stderr, "%s--%d--mkdir %s failure...\n",__FUNCTION__, __LINE__, path);
            return -1;
        }
        return 0;
    }
    if(dp)
        closedir(dp);
    return -1;
}

static int hls_segmenter_get_ip(char *ipaddr)
{
        int sock;
        struct sockaddr_in sin;
        struct ifreq ifr;
        sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock == -1) {
                perror("socket");
                return -1;        
        }
        strncpy(ifr.ifr_name, ETH_NAME, IFNAMSIZ);
        ifr.ifr_name[IFNAMSIZ - 1] = 0;
        if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
                perror("ioctl");
                return -1;
        }

        memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
        sprintf(ipaddr, "%s", inet_ntoa(sin.sin_addr));
        return 0;
}

static int hls_segmenter_get_sys_time(char* localdate)
{
       if(localdate == NULL) {
            fprintf(stderr, "%s--%d--localdate points to null...\n", __FUNCTION__, __LINE__);
            return -1;
       }
        time_t timep;
        struct tm* p;
        time(&timep);
        p = localtime(&timep);

        sprintf(localdate, "%d-%d-%d-%d-%d-%d", 1900 + p->tm_year, 1 + p->tm_mon, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec);
       return 0;
}

static int record_set_index_name(char* index_filename)
{
    char* sys_time[20] = {0};
    hls_segmenter_get_sys_time(sys_time);
    strcat(index_filename, D_ROOT_DIR);
    strcat(index_filename, sys_time);
    strcat(index_filename, ".m3u8");
    fprintf(stdout, "index_filename = %s \n", index_filename);
    return 0;
}

static unsigned long int live_readdata_from_ring_buffer(unsigned char* buf, int size)
{
    struct timeval tv_begin, tv_end;
    unsigned long int actual_size =0;
    actual_size = media_provider_rpid_read(live_rb_id, buf, size);
    
    while(actual_size == 0) {
        usleep(30 * 1000);
        actual_size = media_provider_rpid_read(live_rb_id, buf, size);
    }
    
    HLS_SEG_PRINT(stdout, "%s()--%d--size = %d, actual_size = %d bytes--...\n",  __FUNCTION__, __LINE__, size, actual_size);
    return actual_size;
}

static unsigned long int record_readdata_from_ring_buffer(unsigned char* buf, int size)
{
    struct timeval tv_begin, tv_end;
    unsigned long int actual_size =0;
    actual_size = media_provider_rpid_read(record_rb_id, buf, size);
    
    while(actual_size == 0) {
        usleep(30 * 1000);
        actual_size = media_provider_rpid_read(record_rb_id, buf, size);
    }
    
    HLS_SEG_PRINT(stdout, "%s()--%d--size = %d, actual_size = %d bytes--...\n",  __FUNCTION__, __LINE__, size, actual_size);
    return actual_size;
}

static int live_hls_segmenter_fill_iobuffer(void *opaque, uint8_t *buf, int buf_size)
{
    return live_readdata_from_ring_buffer(buf, buf_size);
}

static int record_hls_segmenter_fill_iobuffer(void *opaque, uint8_t *buf, int buf_size)
{
    return record_readdata_from_ring_buffer(buf, buf_size);
}

static void* record_hls_segmenter_thread()
{ 
    record_terminate_seg = 0;

    int frame_index = 0;

    AVPacket pkt;
    AVFormatContext *input_fmtctx = NULL;
    AVFormatContext *output_fmtctx = NULL;
    
    unsigned char *aviobuffer = NULL;
    char *output_filename = "/data/hls_root/live.ts";
    char *index_filename[100] = {0};            //"/data/hls_root/2015-12-12-12-12-12.m3u8";
    char *sys_time[100] = {0};

    int ret = 0;
    int i = 0;
    int have_key = 0;
    static int first_pkt = 1;

    char* pre_url[100] = {0};

    hls_segmenter_mkdir(D_ROOT_DIR);

    record_set_index_name(index_filename);

    av_register_all();

    aviobuffer = (unsigned char *)av_mallocz(AVIOBUFFER_LENGTH);                         //need to be released after test
    if(aviobuffer == NULL) {
        fprintf(stderr, "av_malloc failure in segmenter...\n");
        return -1;
    }
//    memset(aviobuffer, 0x00, AVIOBUFFER_LENGTH);
    
    input_fmtctx = avformat_alloc_context();
    AVIOContext *avio = avio_alloc_context(aviobuffer, AVIOBUFFER_LENGTH, 0, NULL, record_hls_segmenter_fill_iobuffer, NULL, NULL);
    input_fmtctx->pb = avio;

    ret = avformat_open_input(&input_fmtctx, NULL, NULL, NULL);
    if (ret != 0) {
        fprintf(stderr, "Could not open input stream: %d\n", ret);
        exit(1);
    }
        
    if (avformat_find_stream_info(input_fmtctx, NULL) < 0) {
        fprintf(stderr, "Could not read stream information\n");
        exit(1);
    }
        
    av_dump_format(input_fmtctx, NULL, NULL, NULL);
 
    if (avformat_alloc_output_context2(&output_fmtctx, NULL, "hls", index_filename) < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot open the file %s\n", index_filename);
        return -ENOENT;
    }

    hls_segmenter_set_url(pre_url);
    av_opt_set(output_fmtctx->priv_data, "hls_time", "2", 0);
    av_opt_set(output_fmtctx->priv_data, "hls_base_url", "http://192.168.1.5/", 0);
 
    /* Process transcode parameters */
    for (i = 0; i < input_fmtctx->nb_streams; i++) {
        AVStream *out_stream = NULL;
        AVStream *in_stream = NULL;
        in_stream = input_fmtctx->streams[i];
        out_stream = avformat_new_stream(output_fmtctx, in_stream->codec->codec);
        if (out_stream < 0) {
            av_log(NULL, AV_LOG_ERROR, "Alloc new Stream error\n");
            return -EINVAL;
        }
        avcodec_copy_context(output_fmtctx->streams[i]->codec, input_fmtctx->streams[i]->codec);
        out_stream->codec->codec_tag = 0;
        if (output_fmtctx->oformat->flags & AVFMT_GLOBALHEADER) {
            out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
        }
    }
 
    av_dump_format(output_fmtctx, NULL, index_filename, 1);
 
 
    if (avio_open2(&output_fmtctx->pb, index_filename, AVIO_FLAG_WRITE, &output_fmtctx->interrupt_callback, NULL) < 0) {
        av_log(NULL, AV_LOG_ERROR, "cannot open the output file '%s'\n", index_filename);
        return -ENOENT;
    }
 
    if ((ret = avformat_write_header(output_fmtctx, NULL)) < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot write the header for the file '%s' ret = %d\n", index_filename, ret);
        return -ENOENT;
    }
 
 
    while (1) {
        AVStream *in_stream = NULL;
        AVStream *out_stream = NULL;
        
repeat:
        ret = av_read_frame(input_fmtctx, &pkt);
 
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Read Frame Error, Read Next Frame %d\n", ret);
            goto repeat;
        }
 
 
        if (pkt.pts == AV_NOPTS_VALUE && first_pkt) {
            pkt.pts = pkt.dts;
            first_pkt = 0;
        }
 
        in_stream = input_fmtctx->streams[pkt.stream_index];
        out_stream = output_fmtctx->streams[pkt.stream_index];
 
        pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
        pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
        pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
        pkt.pos = -1;
        ret = av_write_frame(output_fmtctx, &pkt);
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Muxing Error, Discarding One Packet\n");
            continue;
        }
        av_free_packet(&pkt);

        if(record_terminate_seg)
            break;
 
    }
 
    av_write_trailer(output_fmtctx);
    avformat_close_input(&input_fmtctx);
    avio_close(avio);
    avformat_free_context(output_fmtctx);
//    av_free(aviobuffer);

end:
    fprintf(stdout, "Record Segmenting Finish\n");
    return NULL;
}

static void* live_hls_segmenter_thread()
{ 
    live_terminate_seg = 0;

    int frame_index = 0;

    AVPacket pkt;
    AVFormatContext *input_fmtctx = NULL;
    AVFormatContext *output_fmtctx = NULL;
    
    unsigned char *aviobuffer = NULL;
    char *output_filename = "/data/hls_root/live.ts";
    char *index_filename = "/data/hls_root/live.m3u8";

    int ret = 0;
    int i = 0;
    int have_key = 0;
    static int first_pkt = 1;

    char* pre_url[25] = {0};

    hls_segmenter_mkdir(D_ROOT_DIR);

    av_register_all();

    aviobuffer = (unsigned char *)av_mallocz(AVIOBUFFER_LENGTH);                         //need to be released after test
    if(aviobuffer == NULL) {
        fprintf(stderr, "av_malloc failure in segmenter...\n");
        return -1;
    }
//    memset(aviobuffer, 0x00, AVIOBUFFER_LENGTH);
    
    input_fmtctx = avformat_alloc_context();
    AVIOContext *avio = avio_alloc_context(aviobuffer, AVIOBUFFER_LENGTH, 0, NULL, live_hls_segmenter_fill_iobuffer, NULL, NULL);
    input_fmtctx->pb = avio;

    ret = avformat_open_input(&input_fmtctx, NULL, NULL, NULL);
    if (ret != 0) {
        fprintf(stderr, "Could not open input stream: %d\n", ret);
        exit(1);
    }
        
    if (avformat_find_stream_info(input_fmtctx, NULL) < 0) {
        fprintf(stderr, "Could not read stream information\n");
        exit(1);
    }
        
    av_dump_format(input_fmtctx, NULL, NULL, NULL);
 
    if (avformat_alloc_output_context2(&output_fmtctx, NULL, "hls", index_filename) < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot open the file %s\n", index_filename);
        return -ENOENT;
    }

    hls_segmenter_set_url(pre_url);
    av_opt_set(output_fmtctx->priv_data, "segment_time", D_DURATION, 0);
    av_opt_set(output_fmtctx->priv_data, "hls_base_url", pre_url, 0);
 
    for (i = 0; i < input_fmtctx->nb_streams; i++) {    // Process transcode parameters
        AVStream *out_stream = NULL;
        AVStream *in_stream = NULL;
        in_stream = input_fmtctx->streams[i];
        out_stream = avformat_new_stream(output_fmtctx, in_stream->codec->codec);
        if (out_stream < 0) {
            av_log(NULL, AV_LOG_ERROR, "Alloc new Stream error\n");
            return -EINVAL;
        }
        avcodec_copy_context(output_fmtctx->streams[i]->codec, input_fmtctx->streams[i]->codec);
        out_stream->codec->codec_tag = 0;
        if (output_fmtctx->oformat->flags & AVFMT_GLOBALHEADER) {
            out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
        }
    }
 
    av_dump_format(output_fmtctx, NULL, index_filename, 1);
 
    if (avio_open2(&output_fmtctx->pb, index_filename, AVIO_FLAG_WRITE, &output_fmtctx->interrupt_callback, NULL) < 0) {
        av_log(NULL, AV_LOG_ERROR, "cannot open the output file '%s'\n", index_filename);
        return -ENOENT;
    }
 
    if ((ret = avformat_write_header(output_fmtctx, NULL)) < 0) {
        av_log(NULL, AV_LOG_ERROR, "Cannot write the header for the file '%s' ret = %d\n", index_filename, ret);
        return -ENOENT;
    }
 
    while (1) {
        AVStream *in_stream = NULL;
        AVStream *out_stream = NULL;
        
    repeat:
        ret = av_read_frame(input_fmtctx, &pkt);
 
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Read Frame Error, Read Next Frame %d\n", ret);
            goto repeat;
        }
 
        if (pkt.pts == AV_NOPTS_VALUE && first_pkt) {
            pkt.pts = pkt.dts;
            first_pkt = 0;
        }
 
        in_stream = input_fmtctx->streams[pkt.stream_index];
        out_stream = output_fmtctx->streams[pkt.stream_index];
 
        pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
        pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
        pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base);
        pkt.pos = -1;
        ret = av_write_frame(output_fmtctx, &pkt);
        if (ret < 0) {
            av_log(NULL, AV_LOG_ERROR, "Muxing Error, Discarding One Packet\n");
            continue;
        }
        av_free_packet(&pkt);

        if(live_terminate_seg)
            break;
    }
 
    av_write_trailer(output_fmtctx);
    avformat_close_input(&input_fmtctx);
    avio_close(avio);
    avformat_free_context(output_fmtctx);
//    av_free(aviobuffer);

    end:
    fprintf(stdout, "Live Segmenting Finish\n");
    return NULL;
}

static int live_hls_segmenter_start(struct dvbrec_stream_info* stream_info)
{
    live_seg_state = HSS_RUNNING;
    fprintf(stdout, "live_seg_state = HSS_RUNNING...\n");          

    media_provider_io_cmd(live_rb_id, REQUEST_STREAM_START, (UINT32)stream_info,  NULL);
    pthread_create(&live_hls_seg_thread_id, NULL, live_hls_segmenter_thread, NULL);

    return 0;
}

static int live_hls_segmenter_stop()
{
    live_terminate_seg = 1;
    
    pthread_join(live_hls_seg_thread_id, NULL);
    live_seg_state = HSS_IDLE;
    
    fprintf(stdout, "live_seg_state = HSS_IDLE...\n");
    
    return 0;
}

static int record_hls_segmenter_start(struct dvbrec_stream_info* stream_info)
{
    record_seg_state = HSS_RUNNING;
    fprintf(stdout, "record_seg_state = HSS_RUNNING...\n");          

    media_provider_io_cmd(record_rb_id, REQUEST_STREAM_START, (UINT32)stream_info,  NULL);
    pthread_create(&record_hls_seg_thread_id, NULL, record_hls_segmenter_thread, NULL);

    return 0;
}

static int record_hls_segmenter_stop()
{
    record_terminate_seg = 1;
    
    pthread_join(record_hls_seg_thread_id, NULL);
    record_seg_state = HSS_IDLE;
    
    fprintf(stdout, "record_seg_state = HSS_IDLE...\n");
    
    return 0;
}

HLS_RETURN_CODE hls_segmenter_cmd(HLS_SEG_CMD hls_seg_cmd, struct dvbrec_stream_info* stream_info)
{
    HLS_RETURN_CODE ret = HLS_CMD_EXEC_SUCCESS;

    if((CMD_START_LIVE == hls_seg_cmd || CMD_START_RECORD == hls_seg_cmd) && stream_info == NULL)
    {
        fprintf(stderr, "In file %s \n In function %s at L[%d]", __FILE__, __FUNCTION__, __LINE__);
        return HLS_CMD_EXEC_FAILURE;
    }
    
    if((live_seg_state == HSS_IDLE && record_seg_state == HSS_IDLE) || 
        CMD_START_LIVE == hls_seg_cmd || 
        CMD_START_RECORD == hls_seg_cmd)
    {
        fprintf(stdout, "Init Ring Buffer!\n");
        media_provider_init();                                    //initial mediaprovider        
    }

    fprintf(stdout, "pid[0] = %d\npid[1] = %d\npid[2] =  %d\npid[3] =  %d\npid[4] =  %d\n", 
        stream_info->pids[0], 
        stream_info->pids[1], 
        stream_info->pids[2], 
        stream_info->pids[3], 
        stream_info->pids[4]);
   
    switch(live_seg_state)
    {
        case HSS_IDLE:
            if(CMD_START_LIVE == hls_seg_cmd) {
                live_hls_segmenter_start(stream_info);
            }
            break;

        case HSS_RUNNING:
            if(CMD_STOP_LIVE == hls_seg_cmd) {
                live_hls_segmenter_stop();
            }
            break;
            
        default:
            break;
    }

    switch(record_seg_state)
    {
        case HSS_IDLE:
            if(CMD_START_RECORD == hls_seg_cmd) {
                record_hls_segmenter_start(stream_info);
            }
            break;

        case HSS_RUNNING:
            if(CMD_STOP_RECORD == hls_seg_cmd) {
                record_hls_segmenter_stop();
            }
            break;
            
        default:
            break;
    }

    if(live_seg_state == HSS_IDLE && record_seg_state == HSS_IDLE)
    {
        fprintf(stdout, "Destroy Ring Buffer!\n");
        media_provider_del();
    }

    return ret;
}

回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-6-24 16:28:19 | 显示全部楼层
试试segment
你这个是因为dts pts的值设置的问题
一般有两种
1. 源流的dts pts出现了问题
2. 自己rescale的时候dts 和pts计算出了问题

如果是有源流的,可以加上copyts参数试试
回复 支持 反对

使用道具 举报

发表于 2015-6-24 19:45:34 | 显示全部楼层
孙悟空 发表于 2015-6-24 16:28
试试segment
你这个是因为dts pts的值设置的问题
一般有两种

好的,谢谢。
1、确实是有的源流有问题,而且问题大部分发生在264的码流中,对这个ptd与dts的计算规则不是太清楚啊,有没有什么资料能了解一下的。
2、这个copyts怎么加呢?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-6-25 11:26:47 | 显示全部楼层
derekzhuo 发表于 2015-6-24 19:45
好的,谢谢。
1、确实是有的源流有问题,而且问题大部分发生在264的码流中,对这个ptd与dts的计算规则不 ...

只能参考ffmpeg.c里面的代码了,应该是有av_rescale来做的
回复 支持 反对

使用道具 举报

发表于 2015-6-29 17:43:22 | 显示全部楼层
孙悟空 发表于 2015-6-24 16:28
试试segment
你这个是因为dts pts的值设置的问题
一般有两种

求教大师兄,有三个问题想请教你一下:
1、你这个copyts是什么东西啊,找好久都没有找到,倒是看到了一个copy_context的东西,我也试了下,但是还是有问题;
2、现在的这个demo不能删除掉不用的ts文件,想删除的话应该怎么做呢?
3、如果我想用segment来做的话,应该怎么弄呢,有没有demo能让小弟看一下?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-6-29 18:00:44 | 显示全部楼层
derekzhuo 发表于 2015-6-29 17:43
求教大师兄,有三个问题想请教你一下:
1、你这个copyts是什么东西啊,找好久都没有找到,倒是看到了一 ...

-hls_flags delete_segments 应该可以了删除里面的ts了

copyts:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

发表于 2021-9-10 10:41:50 | 显示全部楼层
请问 dts monotonical 问题解决了吗,怎么解决的啊?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|Archiver|ChinaFFmpeg

GMT+8, 2024-4-30 03:14 , Processed in 0.069283 second(s), 13 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表