Giter VIP home page Giter VIP logo

Comments (19)

futzu avatar futzu commented on June 3, 2024 1

I don't see why not.
I currently use video iframes to split segments,
let me see what I can work out for audio.

Adrian

from x9k3.

futzu avatar futzu commented on June 3, 2024 1

I had no problem doing it, let me know if this works for you.

  • I made an audio only ts file
ffmpeg -copyts -i video.ts -vn -c copy  audio.ts

a@debian:~/build/x9k3$ ffprobe -hide_banner audio.ts
Input #0, mpegts, from 'audio.ts':
  Duration: 00:48:04.10, start: 4.220300, bitrate: 159 kb/s
  Program 1 
    Metadata:
      service_name    : Service01
      service_provider: FFmpeg
  Stream #0:0[0x100](und): Audio: aac (LC) ([15][0][0][0] / 0x000F), 44100 Hz, stereo, fltp, 108 kb/s
  • I made a sidecar file of PTS, SCTE35 Cue pairs
a@debian:~/build/x9k3$ cat sidecar.txt
102.805,/DAlAAAAAAAAAP/wFAUAAAABf+/+AJKsov4ADdtEAAEAAAAA7eV+Kg==
177.6,/DAlAAAAAAAAAP/wFAUAAAACf+/+APljwP4ADdtEAAIAAAAACcxDcg====
411.0,/DAlAAAAAAAAAP/wFAUAAAADf+/+AjnqcP4ADdtEAAMAAAAASnrfIQ====
927.697,/DAlAAAAAAAAAP/wFAUAAAAEf+/+BP99uv4ADdtEAAQAAAAAtZKbsQ==
1286.52,/DAlAAAAAAAAAP/wFAUAAAAFf+/+BuxCcP4ADdtEAAUAAAAAxSzhag==
2190.39,/DAlAAAAAAAAAP/wFAUAAAAGf+/+C8WJPP4ADdtEAAYAAAAAM8x/Xw==
2807.71,/DAlAAAAAAAAAP/wFAUAAAAHf+/+DxVLzP4ADdtEAAcAAAAAljzkJg==
2891.63,/DAlAAAAAAAAAP/wFAUAAAAIf+/+D4iK7P4ADdtEAAgAAAAAR8yZag== 
  • x9k3
x9k3 -i audio.ts -s sidecar.txt
  • check for cues in the m3u8
a@debian:~/build/x9k3$ grep -1 CUE-OUT=YES index.m3u8
# Splice Point @ 106.805
#EXT-X-SCTE35:CUE="/DAlAAAAAAAAAP/wFAUAAAABf+/+AJKsov4ADdtEAAEAAAAA7eV+Kg==",CUE-OUT=YES
#EXTINF:2.0898,
--
# Splice Point @ 181.6
#EXT-X-SCTE35:CUE="/DAlAAAAAAAAAP/wFAUAAAACf+/+APljwP4ADdtEAAIAAAAACcxDcg==",CUE-OUT=YES
#EXTINF:2.136233,
--
# Splice Point @ 415.0
#EXT-X-SCTE35:CUE="/DAlAAAAAAAAAP/wFAUAAAADf+/+AjnqcP4ADdtEAAMAAAAASnrfIQ==",CUE-OUT=YES
#EXTINF:2.159455,
--
# Splice Point @ 931.697
#EXT-X-SCTE35:CUE="/DAlAAAAAAAAAP/wFAUAAAAEf+/+BP99uv4ADdtEAAQAAAAAtZKbsQ==",CUE-OUT=YES
#EXTINF:2.112989,
--
# Splice Point @ 1290.52
#EXT-X-SCTE35:CUE="/DAlAAAAAAAAAP/wFAUAAAAFf+/+BuxCcP4ADdtEAAUAAAAAxSzhag==",CUE-OUT=YES
#EXTINF:2.136234,
--
# Splice Point @ 2194.39
#EXT-X-SCTE35:CUE="/DAlAAAAAAAAAP/wFAUAAAAGf+/+C8WJPP4ADdtEAAYAAAAAM8x/Xw==",CUE-OUT=YES
#EXTINF:2.136256,
--
# Splice Point @ 2811.71
#EXT-X-SCTE35:CUE="/DAlAAAAAAAAAP/wFAUAAAAHf+/+DxVLzP4ADdtEAAcAAAAAljzkJg==",CUE-OUT=YES
#EXTINF:2.020144,
  • tested in ffplay
ffplay index.m3u8

from x9k3.

futzu avatar futzu commented on June 3, 2024 1

This should help,
https://github.com/futzu/scte35-threefive/blob/master/Encoding.md
let me know if you have any questions.

from x9k3.

futzu avatar futzu commented on June 3, 2024 1

@josepowera

pip3 install --upgrade x9k3

HLS Tag Options now available

from x9k3.

josepowera avatar josepowera commented on June 3, 2024

Will try this and come back (have to dev first the sidecar generator using live not file -extract PTS and auto use that to generate sidecar)

from x9k3.

futzu avatar futzu commented on June 3, 2024

@josepowera

This is what I use to generate splice inserts.

    from threefive import Cue,SpliceInsert

    def mk_cue(event_id, pts, duration=None):
        """
        mk_cue  make a SCTE-35 Cue
        with a Splice Insert command.
        set duration to make a CUE-OUT,
        
        """
        pts= float(pts)
        cue = Cue()
        # default is a CUE-IN 
        sin = SpliceInsert()
        sin.splice_event_id = event_id
        sin.splice_event_cancel_indicator = False
        sin.out_of_network_indicator = False
        sin.time_specified_flag = False
        sin.program_splice_flag = True
        sin.duration_flag = False
        sin.splice_immediate_flag = True
        sin.unique_program_id = event_id
        sin.avail_num = 0
        sin.avail_expected = 0
        # If we have a duration, make a CUE-OUT
        if duration is not None:
            sin.time_specified_flag = True
            sin.time_specified_flag = True
            sin.break_duration = float(duration)
            sin.break_auto_return = True
            sin.break_duration = duration
            sin.splice_immediate_flag = False
            sin.duration_flag = True
            sin.out_of_network_indicator = True
            sin.pts_time = pts
        cue.command = sin # Add SpliceInsert to the SCTE35 cue
        cue_string = cue.encode()  # Use cue.encode_as_hex() for hex instead of base64
        cue.decode()
        return pts,cue_string

from x9k3.

futzu avatar futzu commented on June 3, 2024

This will be in the next threefive release,
you can use it now.

"""
encode.py

threefive.encode has helper functions for Cue encoding.

"""


from threefive.commands import SpliceNull, SpliceInsert, TimeSignal
from threefive.cue import Cue


def mk_splice_null():
    """
    mk_splice_null returns a Cue
    with a Splice Null
    """
    cue = Cue()
    sn = SpliceNull()
    cue.command = sn
    cue.encode()
    return cue


def mk_time_signal(pts=None):
    """
     mk_time_signal returns a Cue
     with a Time Signal

     if pts is NOT set:
         time_specified_flag   False

    if pts IS set:
         time_specified_flag   True
         pts_time                     pts

    """
    cue = Cue()
    ts = TimeSignal()
    ts.time_specified_flag = False
    if pts:
        pts = float(pts)
        ts.time_specified_flag = True
        ts.pts_time = pts
    cue.command = ts
    cue.encode()
    return cue


def mk_splice_insert(event_id, pts, duration=None):
    """
    mk_cue returns a Cue
    with a Splice Insert.

    splice_event_id = event_id

    If duration is NOT set,
        out_of_network_indicator     False
        time_specified_flag              False
        duration_flag                        False
        splice_immediate_flag         True

    if duration IS set:
        out_of_network_indicator     True
        time_specified_flag               True
        duration_flag                         True
        splice_immediate_flag          False
        break_auto_return                True
        break_duration                      duration
        pts_time                                pts

    """
    pts = float(pts)
    cue = Cue()
    # default is a CUE-IN
    sin = SpliceInsert()
    sin.splice_event_id = event_id
    sin.splice_event_cancel_indicator = False
    sin.out_of_network_indicator = False
    sin.time_specified_flag = False
    sin.program_splice_flag = True
    sin.duration_flag = False
    sin.splice_immediate_flag = True
    sin.unique_program_id = event_id
    sin.avail_num = 0
    sin.avail_expected = 0
    # If we have a duration, make a CUE-OUT
    if duration is not None:
        duration = float(duration)
        sin.time_specified_flag = True
        sin.break_duration = duration
        sin.break_auto_return = True
        sin.splice_immediate_flag = False
        sin.duration_flag = True
        sin.out_of_network_indicator = True
        sin.pts_time = pts
    cue.command = sin  # Add SpliceInsert to the SCTE35 cue
    cue.encode()  
    return cue

from x9k3.

josepowera avatar josepowera commented on June 3, 2024

One more thing I'm searching for (I'm still working on this):
-get combination of PTS (could be begining of first segment for each m3u8) and PROGRAM-DATE-TIME. Even if written to console.
-written EXT-X-PROGRAM-DATE-TIME for live streams
#EXT-X-PROGRAM-DATE-TIME:2022-10-11T18:46:47.257Z
-CUE-OUT-CONT currentTime/totalDuration for segments in the middle of cue-out/ cut-in

from x9k3.

futzu avatar futzu commented on June 3, 2024

I have to say, #EXT-X-PROGRAM-DATE-TIME makes no sense to me. If it's a "live" stream wouldn't the time be the current time?

  • x9k4.py
import datetime
from x9k3 import X9K3


class X9K4(X9K3):
    """
    X9K4 is X9K3 with #EXT-X-PROGRAM-DATE-TIME
    """
    def _write_segment(self):
        """
        _write_segment creates segment file,
        writes segment meta data to self.active_data
        """
        if not self.start:
            return
        seg_file = f"seg{self.seg.seg_num}.ts"
        self.seg.seg_uri = self.mk_uri(self.output_dir, seg_file)
        if self.seg.seg_stop:
            self.seg.seg_time = round(self.seg.seg_stop - self.seg.seg_start, 6)
            if self.live:
                self.cue_out_continue()

#PTS
                self.active_data.write(f'# PTS {round(self.seg.seg_start, 6)}\n')

# EXT-X-PROGRAM-DATE-TIME

                iso8601 = f"{datetime.datetime.utcnow().isoformat()}Z"
                pdt = f"#EXT-X-PROGRAM-DATE-TIME:{iso8601}"
                self.active_data.write(pdt + "\n")

            if self.scte35.cue_tag:
                self.active_data.write(self.scte35.cue_tag + "\n")
                self.scte35.cue_tag = None
            with open(self.seg.seg_uri, "wb+") as a_seg:
                a_seg.write(self.active_segment.getbuffer())
                a_seg.flush()
            del self.active_segment
            self.active_data.write(f"#EXTINF:{self.seg.seg_time},\n")
            self.active_data.write(seg_file + "\n")
            self.seg.seg_start = self.seg.seg_stop
            self.seg.seg_stop += self.seconds
            self.window.append(
                (self.seg.seg_num, self.seg.seg_uri, self.active_data.getvalue())
            )
            self.seg.seg_num += 1


if __name__ == "__main__":
    x9k = X9K4()
    x9k.run()
  • Output
# PTS 21.286556
#EXT-X-PROGRAM-DATE-TIME:2022-10-12T01:47:06.666295Z
#EXTINF:2.002,
seg9.ts

from x9k3.

futzu avatar futzu commented on June 3, 2024

I'm redoing the tag stuff. It will solve the CONT issues. Probably less than a week for me to finish it,

from x9k3.

futzu avatar futzu commented on June 3, 2024

Are you good on this? I'm going to close it if you are, let me know.

from x9k3.

josepowera avatar josepowera commented on June 3, 2024

Yes, also HLS tag option was a great addition. Will reopen another issue as I move forward.

Just regarding #EXT-X-PROGRAM-DATE-TIME - I still believe it is useful for live. If for live stream you know that it has to CUE-OUT on example 06:00:00.000AM you can calculate where this is when you combine PROGRAM-DATE-TIME and segment duration to get correct PTS. Without PROGRAM-DATE-TIME you don't know what delay it took in encoding and have no reference to real clock.

from x9k3.

josepowera avatar josepowera commented on June 3, 2024

Regarding CUE-IN and #EXT-X-DISCONTINUITY tag. As I see example below, #EXT-X-DISCONTINUITY should be on next segment after break not last segment of ad-break. I'm working on live stream not VOD.

using x9ks latest from pip (0.1.45):

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:1566
#PTS 3453.421333
#EXTINF:2.0,
seg1566.ts
#EXT-X-DISCONTINUITY
# Splice Point @ 3456.421333
#EXT-X-CUE-OUT:6.0
#PTS 3457.454667
#EXTINF:3.966666,
seg1567.ts
#EXT-X-DISCONTINUITY
# Splice Point @ 3462.421333
#EXT-X-CUE-IN
#PTS 3463.454667
#EXTINF:3.966666,
seg1568.ts
#PTS 3467.421333
#EXTINF:2.0,

https://stackoverflow.com/questions/47047919/how-does-ext-x-discontinuity-sequence-tag-work-in-hls-m3u8-file
https://developer.apple.com/documentation/http_live_streaming/example_playlists_for_http_live_streaming/incorporating_ads_into_a_playlist example:

#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
ad0.ts
#EXTINF:8.0,
ad1.ts
#EXT-X-DISCONTINUITY
#EXTINF:10.0,
movieA.ts
#EXTINF:10.0,
movieB.ts

Maybe it makes no reason to add discontinuity in x9k3, since discontinuity is needed only if CUE-OUT is actually used (not skipped). In that case application replacing content can also update (add) #EXT-X-DISCONTINUITY.


Are automatic returns (CUE-IN) after CUE-OUT duration supported. At the moment when we add CUE-OUT but no CUE-IN to sidecar -> cue-out-cont will go over cue-out duration. Maybe just add some warning in console if SCTE-35 has "break_auto_return": true, that auto_return will not run.

#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:1876
#EXT-X-CUE-OUT-CONT:11.966666/6.0
#PTS 4941.421333
#EXTINF:2.0,
seg1876.ts
#EXT-X-CUE-OUT-CONT:13.966666/6.0
#PTS 4943.421333
#EXTINF:2.0,
seg1877.ts
#EXT-X-CUE-OUT-CONT:15.966666/6.0
#PTS 4945.421333

used scte-35

{
    "info_section": {
        "table_id": "0xfc",
        "section_syntax_indicator": false,
        "private": false,
        "sap_type": "0x3",
        "sap_details": "No Sap Type",
        "section_length": 47,
        "protocol_version": 0,
        "encrypted_packet": false,
        "encryption_algorithm": 0,
        "pts_adjustment_ticks": 0,
        "pts_adjustment": 0.0,
        "cw_index": "0x0",
        "tier": "0xfff",
        "splice_command_length": 20,
        "splice_command_type": 5,
        "descriptor_loop_length": 10,
        "crc": "0x14e4df6a"
    },
    "command": {
        "command_length": 20,
        "command_type": 5,
        "name": "Splice Insert",
        "time_specified_flag": true,
        "pts_time": 5070.421333,
        "pts_time_ticks": 456337920,
        "break_auto_return": true,
        "break_duration": 6.0,
        "break_duration_ticks": 540000,
        "splice_event_id": 19,
        "splice_event_cancel_indicator": false,
        "out_of_network_indicator": true,
        "program_splice_flag": true,
        "duration_flag": true,
        "splice_immediate_flag": false,
        "unique_program_id": 2,
        "avail_num": 0,
        "avail_expected": 0
    },
    "descriptors": [
        {
            "tag": 0,
            "descriptor_length": 8,
            "name": "Avail Descriptor",
            "identifier": "CUEI",
            "provider_avail_id": 0
        }
    ]
}

from x9k3.

futzu avatar futzu commented on June 3, 2024

'Regarding CUE-IN and #EXT-X-DISCONTINUITY tag. As I see example below, #EXT-X-DISCONTINUITY should be on next segment after break not last segment of ad-break. I'm working on live stream not VOD.'

Damn it, I meant to fix that, I saw that too.

from x9k3.

futzu avatar futzu commented on June 3, 2024

'Are automatic returns (CUE-IN) after CUE-OUT duration supported. At the moment when we add CUE-OUT but no CUE-IN to sidecar -> cue-out-cont will go over cue-out duration. Maybe just add some warning in console if SCTE-35 has "break_auto_return": true, that auto_return will not run.'

Yeah, I see what you're saying,
I agree that needs to be fixed, but it probably wont be anytime soon.

I showed you how to add the #EXT-X-PROGRAM-DATE-TIME and PTS if you want it,
you might want to look at the stream_diff in the output.

./seg3.ts	start: 8.868422	duration: 2.002000	stream diff: 1.950796

Stream diff is the difference between real time playback and segment generation.
The stream diff above means that the last segment was generated 1.950796 seconds ahead of real time playback,
As long as the stream diff stays between -2 and +2, the stream should play without error.

90% of the time, x9k3 is sleeping to slow itself down to keep the sliding window in sync.

I cannot assume that an application will add a DISCONTINUITY and if it's not in place the stream tends to break.

Look, you make a lot of valid points, but I just don't have time to implement all the features you want,
if you want to hire me, I can get on it next week, if not, it won't be any time soon. I am just being honest with you.

from x9k3.

josepowera avatar josepowera commented on June 3, 2024

I fully understand your point of view. My ideas are mostly brainstorming after I'm working around using TS splicing in x9k3 for a few days. Hope more users come to use and find x9k3 useful! Maybe just add license header to source files since I see you already declared MIT license on PIP (https://pypi.org/).

from x9k3.

futzu avatar futzu commented on June 3, 2024

I think I finally fixed the CUE-IN DISCONTINUITY bug.

from x9k3.

futzu avatar futzu commented on June 3, 2024

pypy3 -mpip install --upgrade x9k3

a@debian:~/build/x9k3$ pypy3 x9k3 -h
usage: x9k3.py [-h] [-i INPUT] [-o OUTPUT_DIR] [-s SIDECAR] [-t TIME]
               [-T HLS_TAG] [-w WINDOW_SIZE] [-d] [-l] [-r] [-v] [-p]

optional arguments:
  -h, --help            show this help message and exit
  -i INPUT, --input INPUT
                        Input source, like "/home/a/vid.ts" or
                        "udp://@235.35.3.5:3535" or "https://futzu.com/xaa.ts"
  -o OUTPUT_DIR, --output_dir OUTPUT_DIR
                        Directory for segments and index.m3u8 ( created if it
                        does not exist )
  -s SIDECAR, --sidecar SIDECAR
                        Sidecar file of scte35 cues. each line contains PTS,
                        Cue
  -t TIME, --time TIME  Segment time in seconds ( default is 2)
  -T HLS_TAG, --hls_tag HLS_TAG
                        x_scte35, x_cue, x_daterange, or x_splicepoint
                        (default x_cue)
  -w WINDOW_SIZE, --window_size WINDOW_SIZE
                        sliding window size(default:5)
  -d, --delete          delete segments ( enables --live )
  -l, --live            Flag for a live event ( enables sliding window m3u8 )
  -r, --replay          Flag for replay (looping) ( enables --live and
                        --delete )
  -v, --version         Show version
  • New !
  -p, --program_date_time                              
                        Flag to add Program Date Time tags to index.m3u8 (
                         enables --live)

from x9k3.

josepowera avatar josepowera commented on June 3, 2024

I think I finally fixed the CUE-IN DISCONTINUITY bug.

I'm afraid that #EXT-X-DISCONTINUITY is still 1 segment too fast (I'm running on v.0.1.59). As I understand it should be on seg4967.ts and not on seg4966.ts.

I'm running in HLS LIVE mode with cue-out and cue-in signals sent to sidecar.

current version:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:3
#EXT-X-MEDIA-SEQUENCE:4963
#EXT-X-DISCONTINUITY-SEQUENCE:702
# Splice Point @ 10448.823856
#EXT-X-DISCONTINUITY
#Iframe @ 10448.823856 
#EXT-X-PROGRAM-DATE-TIME:2022-10-27T17:59:21.292480Z
#EXT-X-SCTE35:CUE="/DAvAAAAAAAAAP/wFAUAAAGPf+/+OAt8Yf4ACD1gAAIAAAAKAAhDVUVJAAAAAOynsiA=" ,CUE-OUT=YES 
#EXTINF:2.090,
seg4963.ts
#Iframe @ 10451.099411 
#EXT-X-PROGRAM-DATE-TIME:2022-10-27T17:59:23.590936Z
#EXT-X-SCTE35:CUE="/DAvAAAAAAAAAP/wFAUAAAGPf+/+OAt8Yf4ACD1gAAIAAAAKAAhDVUVJAAAAAOynsiA=" ,CUE-OUT=CONT
#EXTINF:2.067,
seg4964.ts
#Iframe @ 10453.142767 
#EXT-X-PROGRAM-DATE-TIME:2022-10-27T17:59:25.594458Z
#EXT-X-SCTE35:CUE="/DAvAAAAAAAAAP/wFAUAAAGPf+/+OAt8Yf4ACD1gAAIAAAAKAAhDVUVJAAAAAOynsiA=" ,CUE-OUT=CONT
#EXTINF:2.043,
seg4965.ts
# Splice Point @ 10455.186122
#EXT-X-DISCONTINUITY
#Iframe @ 10455.186122 
#EXT-X-PROGRAM-DATE-TIME:2022-10-27T17:59:27.637347Z
#EXT-X-SCTE35:CUE="/DAqAAAAAAAAAP/wDwUAAAGPf0/+OBO5wQACAAAACgAIQ1VFSQAAAADsueIZ" ,CUE-IN=YES 
#EXTINF:2.043,
seg4966.ts
#Iframe @ 10457.4849 
#EXT-X-PROGRAM-DATE-TIME:2022-10-27T17:59:29.957457Z
#EXTINF:2.090,
seg4967.ts

I believe #EXT-X-DISCONTINUITY should be on seg4967.ts and not seg4966.ts (yes I know if this is last segment for VOD you simple can't write it)

seg4965.ts
# Splice Point @ 10455.186122
#Iframe @ 10455.186122 
#EXT-X-PROGRAM-DATE-TIME:2022-10-27T17:59:27.637347Z
#EXT-X-SCTE35:CUE="/DAqAAAAAAAAAP/wDwUAAAGPf0/+OBO5wQACAAAACgAIQ1VFSQAAAADsueIZ" ,CUE-IN=YES 
#EXTINF:2.043,
seg4966.ts
#Iframe @ 10457.4849 
#EXT-X-DISCONTINUITY
#EXT-X-PROGRAM-DATE-TIME:2022-10-27T17:59:29.957457Z
#EXTINF:2.090,
seg4967.ts

from x9k3.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.