AirenSoft / OvenMediaEngine

OvenMediaEngine (OME) is a Sub-Second Latency Live Streaming Server with Large-Scale and High-Definition. #WebRTC #LLHLS
https://OvenMediaEngine.com/ome
GNU Affero General Public License v3.0
2.48k stars 1.05k forks source link

Dumps start on the wrong segment in 0.16.4 #1509

Closed the-real-rusty-shackleford closed 3 months ago

the-real-rusty-shackleford commented 5 months ago

Describe the bug

  1. Start an HLS dump. Wait for a few segments to be written to disk.
  2. Stop the dump.
  3. Start another dump in a different folder on the same stream. Check the chunklist. See that it starts with segments from the previous dump, but those segments are not present in the new folder.

More precisely, the second dump folder starts with, say seg_0_7_video_XwI5NCuh_llhls.m4s, but the chunklist starts with the non-existent seg_0_0_video_XwI5NCuh_llhls.m4s.

Expected behavior The expected behavior is that of version 0.16.3. The chunklist should start with seg_0_7_video_XwI5NCuh_llhls.m4s.

To Reproduce Set Server.xml to

<?xml version="1.0" encoding="UTF-8" ?>

<Server version="8">
    <Name>OvenMediaEngine</Name>
    <!-- Host type (origin/edge) -->
    <Type>origin</Type>
    <!-- Specify IP address to bind (* means all IPs) -->
    <IP>*</IP>
    <PrivacyProtection>false</PrivacyProtection>
    <!-- 
    To get the public IP address(mapped address of stun) of the local server. 
    This is useful when OME cannot obtain a public IP from an interface, such as AWS or docker environment. 
    If this is successful, you can use ${PublicIP} in your settings.
    -->
    <StunServer>stun.ovenmediaengine.com:13478</StunServer>

    <Modules>
        <LLHLS>
            <Enable>true</Enable>
        </LLHLS>
    </Modules>

    <!-- Settings for the ports to bind -->
    <Bind>
        <!-- Enable this configuration if you want to use API Server -->
        <Managers>
            <API>
                <Port>8081</Port>
                <WorkerCount>1</WorkerCount>
            </API>
        </Managers>
        <Providers>
            <!-- Push providers -->
            <RTMP>
                <Port>1935</Port>
                <WorkerCount>1</WorkerCount>
            </RTMP>
        </Providers>

        <Publishers>
            <LLHLS>
                <Port>3333</Port>
                <WorkerCount>1</WorkerCount>
            </LLHLS>
        </Publishers>
    </Bind>
    <Managers>
        <Host>
            <Names>
                <Name>*</Name>
            </Names>
        </Host>
        <API>
            <AccessToken>test:test</AccessToken>
            <CrossDomains>
                <Url>localhost</Url>
            </CrossDomains>
        </API>
    </Managers>
    <VirtualHosts>
        <VirtualHost>
            <Name>default</Name>

            <Host>
                <Names>
                    <Name>*</Name>
                </Names>
            </Host>

            <!-- Settings for applications -->
            <Applications>
                <Application>
                    <Name>app</Name>
                    <!-- Application type (live/vod) -->
                    <Type>live</Type>
                    <OutputProfiles>
                        <OutputProfile>
                            <Name>bypass_stream</Name>
                            <OutputStreamName>${OriginStreamName}</OutputStreamName>

                            <Encodes>
                                <Video>
                                    <Name>bypass_video</Name>
                                    <Bypass>true</Bypass>
                                </Video>
                                <Audio>
                                    <Name>bypass_audio</Name>
                                    <Bypass>true</Bypass>
                                </Audio>
                            </Encodes>
                        </OutputProfile>
                    </OutputProfiles>
                    <Providers>
                        <RTMP />
                    </Providers>
                    <Publishers>
                        <AppWorkerCount>1</AppWorkerCount>
                        <StreamWorkerCount>1</StreamWorkerCount>
                        <RTMPPush></RTMPPush>
                        <SRTPush></SRTPush>
                        <LLHLS>
                            <OriginMode>false</OriginMode>
                            <ChunkDuration>0.5</ChunkDuration>
                            <PartHoldBack>1.5</PartHoldBack>
                            <SegmentDuration>6</SegmentDuration>
                            <SegmentCount>10</SegmentCount>
                            <CrossDomains>
                                <Url>*</Url>
                            </CrossDomains>
                        </LLHLS>
                    </Publishers>
                </Application>
            </Applications>
        </VirtualHost>
    </VirtualHosts>
</Server>

Obtain a test file in MP4 format and name it test.mp4

Put the Server.xml and test.mp4 into a folder.

Run the following script in the folder.

OME_TAG=${1:-0.16.4}

mkdir -p ./data/vod

docker image pull airensoft/ovenmediaengine:$OME_TAG
docker image pull jrottenberg/ffmpeg:4.4-alpine

docker container rm ome-test --force
docker container rm ffmpeg-test --force

echo "Starting OME..."

docker run --rm -d \
  --name ome-test \
  -p 1935:1935 \
  -p 8081:8081 \
  -v $(pwd)/Server.xml:/opt/ovenmediaengine/bin/origin_conf/Server.xml \
  -v ./data/vod:/tmp/ome_vod \
  airensoft/ovenmediaengine:$OME_TAG

echo "Starting ffmpeg..."
sleep 5

docker run --rm -d --name ffmpeg-test -v $(pwd):$(pwd) jrottenberg/ffmpeg:4.4-alpine \
  -re \
  -stream_loop \
  -1 \
  -i $(pwd)/test.mp4 \
  -an -c:v libx264 \
  -preset fast \
  -f flv rtmp://host.docker.internal:1935/app/test \

echo "Trying to start dump..."

# wait for OME to start up
sleep 15

curl \
  -s \
  -X POST \
  -H "Content-Type: application/json" \
  -d @- \
  http://test:test@localhost:8081/v1/vhosts/default/apps/app/streams/test:startHlsDump << EOF
{
  "outputStreamName": "test",
  "id": "1",
  "playlist": ["llhls.m3u8"],
  "outputPath": "/tmp/ome_vod/test_1"
}
EOF

echo ""
echo "Dump started. (1)"

sleep 18

curl http://test:test@localhost:8081/v1/vhosts/default/apps/app/streams/test:stopHlsDump \
  -s \
  -X POST \
  -H "Content-Type: application/json" \
  -d @- << 'EOF'
{
  "outputStreamName": "test",
  "id": "1"
}
EOF

echo "Dump stopped (1)"

curl http://test:test@localhost:8081/v1/vhosts/default/apps/app/streams/test:startHlsDump \
  -s \
  -X POST \
  -H "Content-Type: application/json" \
  -d @- << 'EOF'
{
  "outputStreamName": "test",
  "id": "2",
  "playlist": ["llhls.m3u8"],
  "outputPath": "/tmp/ome_vod/test_2"
}
EOF

echo ""
echo "Dump started. (2)"

echo ""
echo "Segments in Folder test_1:"
ls -1tr data/vod/test_1 | grep seg

echo ""
echo "Segments in chunklist for test_1:"
grep seg data/vod/test_1/chunklist*

echo ""
echo "Segments in Folder test_2:"
ls -1tr data/vod/test_2 | grep seg

echo ""
echo "Segments in chunklist for test_2:"
grep seg data/vod/test_2/chunklist*

After the script completes, you will see output like the following:

Segments in Folder test_2:
seg_0_5_video_RrM7P1qS_llhls.m4s

Segments in chunklist for test_2:
seg_0_0_video_RrM7P1qS_llhls.m4s
seg_0_1_video_RrM7P1qS_llhls.m4s
seg_0_2_video_RrM7P1qS_llhls.m4s
seg_0_3_video_RrM7P1qS_llhls.m4s
seg_0_4_video_RrM7P1qS_llhls.m4s

This demonstrates that although the chunklist should have started at segment 5, it actually starts at segment 0.

If you alter the OME_TAG variable in the script to 0.16.3, the error does not occur.

In addition, notice that the test_1 folder is missing segment 0:

Segments in Folder test_1:
seg_0_1_video_LlSmiW34_llhls.m4s
seg_0_2_video_LlSmiW34_llhls.m4s
seg_0_3_video_LlSmiW34_llhls.m4s
seg_0_4_video_LlSmiW34_llhls.m4s

Segments in chunklist for test_1:
seg_0_0_video_LlSmiW34_llhls.m4s
seg_0_1_video_LlSmiW34_llhls.m4s
seg_0_2_video_LlSmiW34_llhls.m4s
seg_0_3_video_LlSmiW34_llhls.m4s
seg_0_4_video_LlSmiW34_llhls.m4s
getroot commented 5 months ago

I have resolved this regression bug and patched it to the latest master branch. Thank you for reporting the issue.

getroot commented 3 months ago

This patch made it into the 0.16.5 release. If the issue reproduces, please reopen the issue. Thank you.