RTSP(Real Time Streaming Protocol)은 스트리밍 미디어 서버를 컨트롤 하기위한 통신시스템등을 위해 고안된 네트워크 프로토콜입니다. (참고 문서 : RFC2326) 이 프로토콜은 비디오 혹은 오디오 기능을 가진 클라이언트와 실시간으로 미디어 스트리밍하는 시스템에 사용되며, 미디어 서버를 원격으로 제어할 때 씁니다. 명령어는 “PLAY”, “PAUSE” 같이 VCR 동작과 비슷하며 시간 정보를 바탕으로 서버에 접근하게 됩니다.

실제 미디어 스트리밍 데이터를 전송하지 않습니다. 대부분의 RTSP 서버는 RTP 규약을 사용해서 전송 계층으로 실제 오디오/비디오 데이터를 전송합니다.

RTSP 명령어


RTSP 규약은 HTTP 규약하고 비교해볼때, 문법이나 동작이 비슷합니다. 하지만 HTTP가 stateless인 반면에 RTSP는 stateful 규약입니다. 임의의 세션 ID는 세션을 추적할 때마다 사용되는데, 이 방법은 영구 TCP 연결을 필요로 합니다. RTSP 메시지는 클라이언트에서 서버로 갑니다. 만약, 서버에서 오류가 발생한다면 서버는 오류에 대한 응답 코드를 클라이언트로 보내줍니다. 기본적인 RTSP 요청 메시지는 아래와 같으며, 기본 포트는 554번입니다.

편집

OPTIONS

OPTIONS 요청은 서버의 accept 타입을 반환합니다.

C -> S: OPTIONS rtsp://example.com/media.mp3 RTSP/1.0
        CSeq: 1 Require: implicit-play
        Proxy-Require: gzipped-messages
S -> C: RTSP/1.0 200 OK
        CSeq: 1
        Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE

 

 

DESCRIBE

DESCRIBE 요청에는 URL(rtsp://...)이 포함됩니다. 기본 포트 554번은 UDP, TCP 둘 다에 사용됩니다. DESCRIBE에 대한 응답 메시지에는 요청한 것에 대한 설명도 포함되는데, 대개 SDP(Session Description Protocol) 형태를 갖추고 있습니다.

C -> S: OPTIONS rstp://example.com/media.mp4 RTSP/1.0
        CSeq: 2
S -> C: RTSP/1.0 200 OK
        CSeq: 2
        Content-Base: rtsp://example.com/media.mp4
        Content-Type: application/sdp
        Content=-Length: 460
        m=video 0 RTP/AVP 96
        a=control:streamid=0
        a=range:npt=0-7.741000
        a=length:npt=7.741000
        a=rtpmap:96 MP4V-ES/5544
        a=mimetype:string; "video/MP4V-ES"
        a=AvgBitRate:integer;304018
        a=StreamName:string;"hinted video track"
        m=audio 0 RTP/AVP 97
        a=control:streamid=1
        a=range:npt=0-7.712000
        a=length:npt=7.712000
        a=rtpmap:97 mpeg4-generic/32000/2
        a=mimetype:string; "audio/mpeg4-generic"
        a=AvgBitRate:integer;65790
        a=StreamName:string;"hinted audio track"

 

 

SETUP

SETUP 요청은 단일 미디어 스트림이 전송되어야 하는지 규정합니다. 이 요청은 PLAY 요청 하기 전에 마쳐야 합니다. 그리고 요청할 때 미디어 스트림 URL과 전송점을 포함해야 합니다. 전송점에는 RTP 데이터(오디오/비디오), RTCP 데이터(메타 정보)를 전송받기 위한 포트 번호도 포함됩니다.

C -> S: SETUP rtsp://example.com/media.mp4/streamid=0 RTSP/1.0
        CSeq: 3
        Transport: RTP/AVP;unicast;client_port=8000-8001
S -> C: RTSP/1.0 200 OK
        CSeq: 3
        Transport: RTP/AVP;unicast;client_port=8000-8001;server_port=9000-9001;ssrc=1234ABCD
        Session: 12345678

 

 

PLAY

PLAY 요청은 하나 또는 모든 미디어 스트림을 재생시킵니다. PLAY 명령은 다중 요청이 가능합니다. 모든 미디어 스트림 재생을 위해서는 URL 집합체가 요청에 포함되어야 합니다. 재생 범위를 구체적으로 지정할 수도 있습니다. 만약 재생 범위를 지정하지 않으면, 미디어 처음부터 끝까지 재생하게됩니다. 또, 일시 정지 상태라면 일시 정지된 위치부터 재생됩니다.

C -> S: OPTIONS rstp://example.com/media.mp4 RTSP/1.0
        CSeq: 4
        Range: npt=5-20 Session: 12345678
S -> C: RTSP/1.0 200 OK
        CSeq: 4
        Session: 12345678 RTP-Info: url=rtsp://example.com/media.mp4/streamid=0;seq=9810092;trptime=3450012

 

PAUSE

PLAY 요청은 하나 또는 모든 스트림을 재생시킵니다. PLAY 명령은 다중 요청이 가능합니다. 모든 미디어 스트림 재생을 위해서는 URL 집합체가 요청에 포함되어야 합니다. 일시 정지할때 범위를 구체적으로 지정할 수도 있습니다.

C -> S: PAUSE rstp://example.com/media.mp4 RTSP/1.0
        CSeq: 5
        Session: 12345678
S -> C: RTSP/1.0 200 OK
        CSeq: 5
        Session: 12345678

 

RECORD

RECORD 요청은 녹화를 위한 명령어입니다.

C -> S: RECORD rstp://example.com/media.mp4 RTSP/1.0
        CSeq: 6
        Session: 12345678
S -> C: RTSP/1.0 200 OK
        CSeq: 6
        Session: 12345678

 

TEARDOWN

TEARDOWN 요청은 세션을 종료하기 위한 명령어이고, 모든 미디어 스트림의 재생을 중단하고 서버에 있는 관련 데이터에 걸린 모든 세션도 해제합니다.

C -> S: OPTIONS rstp://example.com/media.mp4 RTSP/1.0
        CSeq: 8
        Range: npt=5-20
        Session: 12345678
S -> C: RTSP/1.0 200 OK
        CSeq: 8
        Session: 12345678

 

RTSP 서버/클라이언트 종류

Server

Darwin Streaming Server, Feng, GStreamer, Hlix DNA Server, Helix Universal Server, LEADTOOLS Media Streaming Server SDK, LIVE555 liveMedia / openRTSP, Managed FMedia Aggregation, Nimble Streamer, pvServer, QuickTime Streaming Server, SharpRTSP, TV Server, ViaMotion, VideoLAN, VX30, Windows Media Services, Wowza Streaming Engine, Xenon Streamfing Server, YouTube

 

Client

Astra, cURL, FFmpeg, GStreamer, JetAudio, LIVE555 liveMedia / oepnRTSP, Media Play Classic, MPlayer, MythTV, Managed Media Aggregation, omxplayer, QuickTime, RealPlayer, SharpRTSP, Skype, Spotify, VLC media player, Winamp, Windows Media Player, xine

 

출처: https://12bme.tistory.com/345

'Media' 카테고리의 다른 글

Resolution  (0) 2021.09.24

Equals()

public static bool ReferenceEquals(object left, object right);
public static bool Equals(object left, object right);
// 재정의하는 경우 IEquatable<T>를 구현해야 한다.
// (값에 고유의 의미 체계를 부여하기 위해 IStructuralEquality를 구현하기도 함)
public virtual bool Equals(object right);
// 주로 성능을 개선하기 위해 재정의
public static bool operator == (MyClass left, MyClass right);
  • 참조 타입의 경우, 참조 대상이 같으면 동일하다고 간주
  • 값 타입의 경우, 두 객체의 타입과 값의 내용이 일치해야만 동일한 객체로 판단
public static bool Equals(object left, object right)
{
    if (object.ReferenceEquals(left, right))
        return true;
 
    if (object.ReferenceEquals(left, null) ||
        object.ReferenceEquals(right, null))
        return false;
 
    return left.Equals(right);
}

동일성의 수학적 속성

  • 반사적 속성(reflexive property)
    • 어떤 객체든 자기 자신과는 항상 같아야 한다.
  • 대칭적 속성(symmetric property)
    • 동일성의 결과가 비교 순서와는 무관해야 한다.
  • 추이적 속성(transitive property)
    • if (a == b) and (b == c), a == c

 

IEquatable<T>

public class MyClass : IEquatable<MyClass>
{
    public override bool Equals(object other)
    {
        // C# 메서드 내에서 this는 절대 null이 될 수 없다.
        if (object.ReferenceEquals(right, null))
            return false;

        if (object.ReferenceEquals(this, other))
            return true;

        if (this.GetType() != other.GetType())
            return false;

        return this.Equals(other as MyCalss)
    }

    // IEquatable<MyClass>
    public bool Equals(MyClass other)
    {
        ;
    }
}

'.NET > C#' 카테고리의 다른 글

Concurrency (동시성)  (0) 2023.08.16
Marshaling: 복사 및 고정  (0) 2021.10.15
Array Marshaling  (0) 2021.10.15
Comparisons and Sorts  (0) 2021.10.15
Debugging Tips  (0) 2021.09.15
#include <cstdlib>
#include <iostream>
#include <chrono>
#include <ctime>
#include <queue>
using namespace std;
 
int main()
{
    // your code goes here
 
    std::chrono::steady_clock::time_point t0, t1, tp;
    int isNotFirst = 0;
    double elapsed_s = 0, g_samples_s = 0;
    std::queue<double> g_fps;
    size_t nb_samples;
 
    for (int i = 0; i < 10; ++i)
    {
        t0 = std::chrono::steady_clock::now();
 
        int r = (std::rand() % 10) + 25; // 25 ~ 34
        std::this_thread::sleep_for(std::chrono::milliseconds(r));
 
        t1 = std::chrono::steady_clock::now();
        elapsed_s = (double)r / 1000;//std::chrono::duration_cast<std::chrono::duration<double>(t1 - t0).count();
 
        double fps = 0, avg_fps = 0;
 
        if (isNotFirst)
        {
            nb_samples = g_fps.size();
            elapsed_s = r;//std::chrono::duration_cast<std::chrono::duration<double>>(t0 - tp).count();
 
            g_samples_s += elapsed_s;
            g_fps.push(elapsed_s);
 
            if (nb_samples >= 10)
            {
                g_samples_s -= g_fps.front();
                   g_fps.pop();
            }
            else nb_samples++;
 
            fps = 1 / elapsed_s;
            avg_fps = nb_samples / g_samples_s;
        }
 
        tp = t0;
        isNotFirst = 1;
 
        printf("%d. %.2f/%.2f fps\r\n", i, fps, avg_fps);
    }
 
    return 0;
}

'C, C++' 카테고리의 다른 글

xlnt - XLSX 파일 다루기  (0) 2022.12.22
To install the MinGW-w64 toolchain  (0) 2022.10.28
문자열 구분자로 분리  (0) 2021.10.20
VSCode + vcpkg  (0) 2021.10.19
Get DLL path at run time  (0) 2021.10.05
<Style TargetType="{x:Type DataGrid}">
    <Setter Property="RowStyle">
        <Setter.Value>
            <Style TargetType="{x:Type DataGridRow}">
                <Setter Property="BorderBrush"
                        Value="{StaticResource ContentBgColorKey}"/>
                <Setter Property="BorderThickness" Value="0"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type DataGridRow}">
                            <Border x:Name="DGR_Border"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    SnapsToDevicePixels="True">
                                <Grid>
                                    <SelectiveScrollingGrid>
                                        <SelectiveScrollingGrid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition/>
                                        </SelectiveScrollingGrid.ColumnDefinitions>
                                                
                                        <DataGridCellsPresenter Grid.Column="1"
                                                                ItemsPanel="{TemplateBinding ItemsPanel}"
                                                                SnapsToDevicePixels="True"/>

                                        <DataGridRowHeader
                                            SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
                                            Visibility="{Binding HeadersVisibility,
                                                                 Converter={x:Static DataGrid.HeadersVisibilityConverter},
                                                                 ConverterParameter={x:Static DataGridHeadersVisibility.Row},
                                                                 RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
                                    </SelectiveScrollingGrid>

                                    <Rectangle x:Name="PART_Box"
                                               Margin="0,0,1,0"
                                               Stroke="Orange"
                                               StrokeThickness="1"
                                               Fill="{x:Null}"
                                               Visibility="Hidden"/>
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="True">
                                <Setter TargetName="PART_Box"
                                        Property="Visibility" Value="Visible"/>
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

 

<Style TargetType="{x:Type DataGrid}">
    <Style.Resources>
        <Style x:Key="{ComponentResourceKey ResourceId=DataGridSelectAllButtonStyle, TypeInTargetAssembly={x:Type DataGrid}}"
               TargetType="{x:Type Button}">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="0"/>
        </Style>
    </Style.Resources>
</Style>

+ Recent posts