Exemple #1
0
async def test_hls_playlist_view(hass, hls_stream, stream_worker_sync):
    """Test rendering the hls playlist with 1 and 2 output segments."""
    await async_setup_component(hass, "stream", {"stream": {}})

    stream = create_stream(hass, STREAM_SOURCE)
    stream_worker_sync.pause()
    hls = stream.add_provider("hls")

    hls.put(Segment(1, INIT_BYTES, MOOF_BYTES, DURATION))
    await hass.async_block_till_done()

    hls_client = await hls_stream(stream)

    resp = await hls_client.get("/playlist.m3u8")
    assert resp.status == 200
    assert await resp.text() == make_playlist(sequence=1,
                                              segments=[make_segment(1)])

    hls.put(Segment(2, INIT_BYTES, MOOF_BYTES, DURATION))
    await hass.async_block_till_done()
    resp = await hls_client.get("/playlist.m3u8")
    assert resp.status == 200
    assert await resp.text() == make_playlist(
        sequence=1, segments=[make_segment(1),
                              make_segment(2)])

    stream_worker_sync.resume()
    stream.stop()
Exemple #2
0
async def test_hls_playlist_view_discontinuity(hass, hls_stream,
                                               stream_worker_sync):
    """Test a discontinuity across segments in the stream with 3 segments."""
    await async_setup_component(hass, "stream", {"stream": {}})

    stream = create_stream(hass, STREAM_SOURCE)
    stream_worker_sync.pause()
    hls = stream.add_provider("hls")

    hls.put(Segment(1, INIT_BYTES, MOOF_BYTES, DURATION, stream_id=0))
    hls.put(Segment(2, INIT_BYTES, MOOF_BYTES, DURATION, stream_id=0))
    hls.put(Segment(3, INIT_BYTES, MOOF_BYTES, DURATION, stream_id=1))
    await hass.async_block_till_done()

    hls_client = await hls_stream(stream)

    resp = await hls_client.get("/playlist.m3u8")
    assert resp.status == 200
    assert await resp.text() == make_playlist(
        sequence=1,
        segments=[
            make_segment(1),
            make_segment(2),
            make_segment(3, discontinuity=True),
        ],
    )

    stream_worker_sync.resume()
    stream.stop()
Exemple #3
0
async def test_recorder_discontinuity(tmpdir):
    """Test recorder save across a discontinuity."""
    # Setup
    source = generate_h264_video()
    filename = f"{tmpdir}/test.mp4"

    # Run
    recorder_save_worker(filename, [Segment(1, source, 4, 0), Segment(2, source, 4, 1)])

    # Assert
    assert os.path.exists(filename)
Exemple #4
0
async def test_hls_max_segments_discontinuity(hass, hls_stream, stream_worker_sync):
    """Test a discontinuity with more segments than the segment deque can hold."""
    await async_setup_component(hass, "stream", {"stream": {}})

    stream = create_stream(hass, STREAM_SOURCE)
    stream_worker_sync.pause()
    hls = stream.add_provider(HLS_PROVIDER)

    hls_client = await hls_stream(stream)

    hls.put(
        Segment(
            1,
            INIT_BYTES,
            MOOF_BYTES,
            SEGMENT_DURATION,
            stream_id=0,
            start_time=FAKE_TIME,
        )
    )

    # Produce enough segments to overfill the output buffer by one
    for sequence in range(1, MAX_SEGMENTS + 2):
        hls.put(
            Segment(
                sequence,
                INIT_BYTES,
                MOOF_BYTES,
                SEGMENT_DURATION,
                stream_id=1,
                start_time=FAKE_TIME,
            )
        )
    await hass.async_block_till_done()

    resp = await hls_client.get("/playlist.m3u8")
    assert resp.status == 200

    # Only NUM_PLAYLIST_SEGMENTS are returned in the playlist causing the
    # EXT-X-DISCONTINUITY tag to be omitted and EXT-X-DISCONTINUITY-SEQUENCE
    # returned instead.
    start = MAX_SEGMENTS + 2 - NUM_PLAYLIST_SEGMENTS
    segments = []
    for sequence in range(start, MAX_SEGMENTS + 2):
        segments.append(make_segment(sequence))
    assert await resp.text() == make_playlist(
        sequence=start,
        discontinuity_sequence=1,
        segments=segments,
    )

    stream_worker_sync.resume()
    stream.stop()
Exemple #5
0
async def test_hls_max_segments(hass, hls_stream, stream_worker_sync):
    """Test rendering the hls playlist with more segments than the segment deque can hold."""
    await async_setup_component(hass, "stream", {"stream": {}})

    stream = create_stream(hass, STREAM_SOURCE, {})
    stream_worker_sync.pause()
    hls = stream.add_provider(HLS_PROVIDER)

    hls_client = await hls_stream(stream)

    # Produce enough segments to overfill the output buffer by one
    for sequence in range(MAX_SEGMENTS + 1):
        segment = Segment(sequence=sequence,
                          duration=SEGMENT_DURATION,
                          start_time=FAKE_TIME)
        hls.put(segment)
        await hass.async_block_till_done()

    resp = await hls_client.get("/playlist.m3u8")
    assert resp.status == 200

    # Only NUM_PLAYLIST_SEGMENTS are returned in the playlist.
    start = MAX_SEGMENTS + 1 - NUM_PLAYLIST_SEGMENTS
    segments = []
    for sequence in range(start, MAX_SEGMENTS + 1):
        segments.append(make_segment(sequence))
    assert await resp.text() == make_playlist(sequence=start,
                                              segments=segments)

    # Fetch the actual segments with a fake byte payload
    for segment in hls.get_segments():
        segment.init = INIT_BYTES
        segment.parts = [
            Part(
                duration=SEGMENT_DURATION,
                has_keyframe=True,
                data=FAKE_PAYLOAD,
            )
        ]

    # The segment that fell off the buffer is not accessible
    segment_response = await hls_client.get("/segment/0.m4s")
    assert segment_response.status == 404

    # However all segments in the buffer are accessible, even those that were not in the playlist.
    for sequence in range(1, MAX_SEGMENTS + 1):
        segment_response = await hls_client.get(f"/segment/{sequence}.m4s")
        assert segment_response.status == 200

    stream_worker_sync.resume()
    stream.stop()
async def test_recorder_save(tmpdir):
    """Test recorder save."""
    # Setup
    source = generate_h264_video()
    filename = f"{tmpdir}/test.mp4"

    # Run
    segment = Segment(sequence=1)
    add_parts_to_segment(segment, source)
    segment.duration = 4
    recorder_save_worker(filename, [segment])

    # Assert
    assert os.path.exists(filename)
Exemple #7
0
async def test_recorder_discontinuity(tmpdir):
    """Test recorder save across a discontinuity."""
    # Setup
    source = generate_h264_video()
    filename = f"{tmpdir}/test.mp4"

    # Run
    init, moof_data = get_init_and_moof_data(source.getbuffer())
    recorder_save_worker(
        filename,
        [
            Segment(1, init, moof_data, 4, 0),
            Segment(2, init, moof_data, 4, 1),
        ],
    )

    # Assert
    assert os.path.exists(filename)
Exemple #8
0
async def test_hls_playlist_view_discontinuity(hass, hls_stream,
                                               stream_worker_sync):
    """Test a discontinuity across segments in the stream with 3 segments."""
    await async_setup_component(hass, "stream", {"stream": {}})

    stream = create_stream(hass, STREAM_SOURCE, {})
    stream_worker_sync.pause()
    hls = stream.add_provider(HLS_PROVIDER)

    segment = Segment(sequence=0,
                      stream_id=0,
                      duration=SEGMENT_DURATION,
                      start_time=FAKE_TIME)
    hls.put(segment)
    segment = Segment(sequence=1,
                      stream_id=0,
                      duration=SEGMENT_DURATION,
                      start_time=FAKE_TIME)
    hls.put(segment)
    segment = Segment(
        sequence=2,
        stream_id=1,
        duration=SEGMENT_DURATION,
        start_time=FAKE_TIME,
    )
    hls.put(segment)
    await hass.async_block_till_done()

    hls_client = await hls_stream(stream)

    resp = await hls_client.get("/playlist.m3u8")
    assert resp.status == 200
    assert await resp.text() == make_playlist(
        sequence=0,
        segments=[
            make_segment(0),
            make_segment(1),
            make_segment(2, discontinuity=True),
        ],
    )

    stream_worker_sync.resume()
    stream.stop()
Exemple #9
0
async def test_recorder_save(tmpdir):
    """Test recorder save."""
    # Setup
    source = generate_h264_video()
    filename = f"{tmpdir}/test.mp4"

    # Run
    recorder_save_worker(filename, [Segment(1, source, 4)], "mp4")

    # Assert
    assert os.path.exists(filename)
Exemple #10
0
async def test_recorder_save(tmpdir):
    """Test recorder save."""
    # Setup
    source = generate_h264_video()
    filename = f"{tmpdir}/test.mp4"

    # Run
    recorder_save_worker(
        filename, [Segment(1, *get_init_and_moof_data(source.getbuffer()), 4)])

    # Assert
    assert os.path.exists(filename)
async def test_recorder_save():
    """Test recorder save."""
    # Setup
    source = generate_h264_video()
    output = BytesIO()
    output.name = "test.mp4"

    # Run
    recorder_save_worker(output, [Segment(1, source, 4)])

    # Assert
    assert output.getvalue()
Exemple #12
0
async def test_hls_playlist_view(hass, hls_stream, stream_worker_sync):
    """Test rendering the hls playlist with 1 and 2 output segments."""
    await async_setup_component(hass, "stream", {"stream": {}})

    stream = create_stream(hass, STREAM_SOURCE, {})
    stream_worker_sync.pause()
    hls = stream.add_provider(HLS_PROVIDER)

    for i in range(2):
        segment = Segment(sequence=i,
                          duration=SEGMENT_DURATION,
                          start_time=FAKE_TIME)
        hls.put(segment)
    await hass.async_block_till_done()

    hls_client = await hls_stream(stream)

    resp = await hls_client.get("/playlist.m3u8")
    assert resp.status == 200
    assert await resp.text() == make_playlist(
        sequence=0, segments=[make_segment(0),
                              make_segment(1)])

    segment = Segment(sequence=2,
                      duration=SEGMENT_DURATION,
                      start_time=FAKE_TIME)
    hls.put(segment)
    await hass.async_block_till_done()
    resp = await hls_client.get("/playlist.m3u8")
    assert resp.status == 200
    assert await resp.text() == make_playlist(
        sequence=0,
        segments=[make_segment(0),
                  make_segment(1),
                  make_segment(2)])

    stream_worker_sync.resume()
    stream.stop()
Exemple #13
0
async def test_hls_max_segments(hass, hls_stream, stream_worker_sync):
    """Test rendering the hls playlist with more segments than the segment deque can hold."""
    await async_setup_component(hass, "stream", {"stream": {}})

    stream = create_stream(hass, STREAM_SOURCE)
    stream_worker_sync.pause()
    hls = stream.add_provider(HLS_PROVIDER)

    hls_client = await hls_stream(stream)

    # Produce enough segments to overfill the output buffer by one
    for sequence in range(1, MAX_SEGMENTS + 2):
        hls.put(
            Segment(
                sequence,
                INIT_BYTES,
                MOOF_BYTES,
                SEGMENT_DURATION,
                start_time=FAKE_TIME,
            )
        )
        await hass.async_block_till_done()

    resp = await hls_client.get("/playlist.m3u8")
    assert resp.status == 200

    # Only NUM_PLAYLIST_SEGMENTS are returned in the playlist.
    start = MAX_SEGMENTS + 2 - NUM_PLAYLIST_SEGMENTS
    segments = []
    for sequence in range(start, MAX_SEGMENTS + 2):
        segments.append(make_segment(sequence))
    assert await resp.text() == make_playlist(
        sequence=start,
        segments=segments,
    )

    # The segment that fell off the buffer is not accessible
    segment_response = await hls_client.get("/segment/1.m4s")
    assert segment_response.status == 404

    # However all segments in the buffer are accessible, even those that were not in the playlist.
    for sequence in range(2, MAX_SEGMENTS + 2):
        segment_response = await hls_client.get(f"/segment/{sequence}.m4s")
        assert segment_response.status == 200

    stream_worker_sync.resume()
    stream.stop()
async def test_recorder_discontinuity(tmpdir):
    """Test recorder save across a discontinuity."""
    # Setup
    source = generate_h264_video()
    filename = f"{tmpdir}/test.mp4"

    # Run
    segment_1 = Segment(sequence=1, stream_id=0)
    add_parts_to_segment(segment_1, source)
    segment_1.duration = 4
    segment_2 = Segment(sequence=2, stream_id=1)
    add_parts_to_segment(segment_2, source)
    segment_2.duration = 4
    recorder_save_worker(filename, [segment_1, segment_2])
    # Assert
    assert os.path.exists(filename)