1.시스템&인프라/스트리밍

[MistServer]8. MistServer Stream 관리 API 사용 예제

쿼드큐브 2025. 4. 14. 10:54
728x90

MistServer의 스트림을 효과적으로 제어할 수 있는 API 사용법을 정리했습니다.
스트림 추가, 삭제, 강제 종료, 통계 조회 등 MistServer 스트림 관리에 필요한 주요 기능을 정리했습니다.

 

MistServer Stream 관리 API 사용 예제

 

목차

1. MistServer API 인증 방식 및 주요 API 목록

2. 스트림 개별 추가 및 업데이트: addstream

3. 스트림 삭제: deletestream / deletestreamsource

4. 스트림 강제 종료: nuke_stream

5. 미등록 스트림 자동 정리: no_unconfigured_streams

6. 현재 활성화 스트림 조회: active_streams

7. 스트림 통계 조회: stats_streams

8. 스트림 세션 강제 종료: stop_sessions

관련 글 링크

 

 

1. MistServer API 인증 방식 및 주요 API 목록

◆ MistServer API 인증 방식 

  • MistServer API를 사용하려면 사용자 인증이 필요합니다.
  • challenge 기반 이중 해싱(MD5) 방식으로 암호를 생성해야 합니다.
import hashlib

def generate_password(password, challenge):
    md5_pwd = hashlib.md5(password.encode()).hexdigest()
    return hashlib.md5((md5_pwd + challenge).encode()).hexdigest()
password  = MD5( MD5(“비밀번호”) + challenge)
challenge는 MistServer API 호출 시 받아온 값을 사용해야 합니다.

 

◆ Stream 관리 주요 API 

API 명 설명
Streams 전체 스트림 목록을 "설정"하는 용도
Addstream 스트림을 개별적으로 추가/업데이트하는 기능 (기존 목록 유지)
Deletestream 특정 스트림만 개별 삭제하는 기능
Deletestreamsource 스트림 및 해당 소스 삭제
Nuke_stream 스트림을 완전히 종료 및 재설정
No_unconfigured_streams 설정되지 않은 스트림 제거
Active_streams 현재 활성화된 스트림 목록 조회
Stats_streams 최근 10분 동안 활성화된 스트림 목록을 가져옴
Stop_sessions 특정 스트림 또는 프로토콜을 사용하는 세션 종료

 

 

2. 스트림 개별 추가 및 업데이트: addstream

기존 스트림을 변경하지 않고 새로운 스트림을 추가하거나 기존 스트림을 업데이트할 때 사용됩니다.

빈 addstream 요청을 보내더라도 모든 스트림이 삭제되지 않습니다.

요청 후 응답(streams 결과)에는 전체 스트림 목록이 아닌, 새로 추가되거나 업데이트된 스트림만 포함됩니다.

이를 구별하기 위해 응답 스트림 목록에 "incomplete list":1 항목이 추가됩니다.

#요청문 Python 코드
import requests
url = "http://192.168.1.70:4242/api2"
payload = {
    "authorize": {
        "username": "user_id",
        "password": "8053fbe0ddd8159f000bb03eaf9853d0"
    },
    "addstream": {
        "stream01": {             # 스트림명      
          "source": "push://",    # 스트림 소스  
          "stop_sessions": false, #true로 설정하면 해당 스트림과 관련된 모든 세션을 중단
          "resume" : 1,           #스트림 재개 기능 여부 (null이면 기본값) 
          "segmentsize": "1900"   #세그먼트 크기(ms) 설정 (예: 6000 → 6초)
        }
        "stream02": {
            "source": "push://",
            "stop_sessions": False,
            "resume": 1,
            "segmentsize": "1900"
        }
    }
}
headers = {"content-type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.json())

#응답 JSON 예시
{
  "LTS": 1,
  "authorize": {
    "status": "OK"
  },
  "streams": {
    "incomplete list": 1,
    "stream01": {
      "name": "stream01",
      "resume": 1,
      "segmentsize": "1900",
      "source": "push://",
      "stop_sessions": false
    },
    "stream02": {
      "name": "stream02",
      "resume": 1,
      "segmentsize": "1900",
      "source": "push://",
      "stop_sessions": false
    }
  }
}
스트림 전체 설정 : streams
스트림 목록을 전체 덮어쓰기(Overwrite) 방식으로 설정합니다.
한 번의 요청으로 모든 스트림을 교체하며, 빈 요청 시 모든 스트림이 삭제되므로 주의가 필요합니다.
대신, 개별 추가/삭제는 addstream, deletestream 사용 권장

 

 

3. 스트림 삭제: deletestream / deletestreamsource

◆ deletestream  

  • 특정 스트림만 삭제할 때 사용되며,  다른 스트림에는 영향을 주지 않습니다.
  • 즉, 일부 스트림만 선택적으로 삭제할 수 있습니다.
# 요청문 Python 예시
import requests
url = "http://192.168.1.70:4242/api2"
payload = {
    "authorize": {
        "username": "user_id",
        "password": "8053fbe0ddd8159f000bb03eaf9853d0"
    },
# 스트림명이 하나일 경우 "deletestream":"stream01" 처럼 사용해도 됨    
    "deletestream": ["stream03", "stream01"]
}
headers = {"content-type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.json())

#응답 JSON 예
{
  "LTS": 1,
  "authorize": {
    "status": "OK"
  },
  "streams": {
    "incomplete list": 1
  }
}

 

◆ deletestreamsource  

  • DeleteStreamSource 호출은 특정 스트림을 소스 파일과 함께 삭제하는 API입니다.
  • 이 호출은 다른 스트림에는 영향을 주지 않습니다.
  • 삭제할 스트림과 연결된 소스 파일이 존재하면, 그 파일도 삭제를 시도합니다.
  • 단, HLS 플레이리스트 같은 다중 파일 스트림은 삭제되지 않습니다.
  • 만약 DTSH 헤더 파일이 존재하면, 해당 파일도 삭제 시도합니다.
#요청문 Python 코드
import requests
url = "http://192.168.1.70:4242/api2"

payload = {
    "authorize": {
        "username": "user_id",
        "password": "8053fbe0ddd8159f000bb03eaf9853d0"
    },
#스트림명이 하나일 경우 "deletestreamsource":"stream01" 처럼 사용해도 됨
    "deletestreamsource": ["stream01"]
}
headers = {"content-type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.json())

#응답문 Json 예시
{
  "LTS": 1,
  "authorize": {
    "status": "OK"
  },
  "deletestreamsource": [
    "-1: Stream deleted, source remains"
  ]
}

응답코드:
0: No action taken
1: Source file deleted
2: Source file and dtsh deleted
  : Stream deleted, source remains
  : Stream and source file deleted
  : Stream, source file and dtsh deleted

음수 값: 서버 설정에서 스트림이 제거됨을 의미
양수 값: 스트림이 서버 설정에서 제거되지 않았음을 의미

 

 

4. 스트림 강제 종료: nuke_stream

Nuke_Stream 호출은 실행 중인 스트림을 완전히 종료하고,메모리에 남아 있는 스트림 데이터를 정리하는 기능을 수행하는 API입니다.

이 API는 일반적인 스트림 종료보다 더 강력한 방식으로 스트림을 종료하며, 3단계에 걸쳐 완전한 종료 및 메모리 정리를 시도합니다.

1단계: 정상 종료 시도
   - 먼저 정상적인 방식으로 스트림을 종료하려고 시도합니다.
   - 일반적인 종료 절차를 수행하여 가능한 한 부드럽게 스트림을 중단합니다.
2단계: 강제 종료
   - 1단계에서 스트림이 정상적으로 종료되지 않으면,
   - 강제 종료(Force Stop)를 실행하여 스트림을 강제로 중지합니다.
   - 스트림이 네트워크 문제로 응답하지 않거나,프로세스가 멈춰 있을 경우 강제 종료하여 제거합니다.
3단계: 메모리 정리
   - 스트림이 종료된 후에도 서버 메모리에 남아 있는 데이터가 있는지 확인합니다.
   - 만약 캐시나 임시 데이터가 남아 있다면 이를 제거하여,서버 성능을 최적화합니다.
  • Nuke_Stream vs. 다른 스트림 종료 API 비교
API 기능
DeleteStream 특정 스트림을 제거하지만, 실행 중인 스트림을 강제 종료하지 않음
DeleteStreamSource 특정 스트림과 관련된 소스 파일까지 삭제
Nuke_Stream 실행 중인 스트림을 완전히 종료하고 메모리에서 정리
#요청문 python 코드
import requests
url = "http://192.168.1.70:4242/api2"
payload = {
    "authorize": {
        "username": "user_id",
        "password": "8053fbe0ddd8159f000bb03eaf9853d0"
    },
    "nuke_stream": "stream01"
}
headers = {"content-type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.json())

#응답 JSON 예시
{
  "LTS": 1,
  "authorize": {
    "status": "OK"
  }
}

 

5. 미등록 스트림 자동 정리: no_unconfigured_streams

No_Unconfigured_Streams 호출은 현재 실행 중인 스트림과 시스템에 설정된 스트림을 비교하여

설정되지 않은 스트림(Unconfigured Streams) 또는 설정된 소스(Source)와 다른 소스를 사용하는 스트림을 

자동으로 Nuke_Stream을 호출하여 제거하는 기능을 수행합니다.

이를 활용하면 불법 스트리밍 차단, 스트리밍 서버 보호, 리소스 최적화 등의 효과를 얻을 수 있습니다.

#요청문 Python 코드
import requests
url = "http://192.168.1.70:4242/api2"
payload = {
    "authorize": {
        "username": "user_id",
        "password": "8053fbe0ddd8159f000bb03eaf9853d0"
    },
    "no_unconfigured_streams": 1
}
headers = {"content-type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.json())

#응답 JSON 예시
{
  "LTS": 1,
  "authorize": {
    "status": "OK"
  }
}

 

 

6. 현재 활성화 스트림 조회: active_streams

현재 실행 중(active)인 스트림 목록을 요청하는 API입니다.

등록된 스트림만이 아니라, 일시적으로 실행 중인 스트림, 와일드카드(*) 기반의 스트림도 포함됩니다.

즉, 현재 MistServer에서 실제로 활성화된 스트림만 조회할 수 있습니다.

#요청문 Python 코드
import requests
url = "http://192.168.1.70:4242/api2"
payload = {
    "authorize": {
        "username": "user_id",
        "password": "8053fbe0ddd8159f000bb03eaf9853d0"
    },
    "active_streams": True
}
headers = {"content-type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.json())


#요청예시 : 특정 스트림 + 여러정보 요청
{
  "active_streams": {
    "fields": ["clients", "upbytes", "downbytes"], # 요청할 필드 선택
    "streams": ["stream1", "stream2"], # 특정 스트림만 조회
    "longform": false # (기본값) 간략한 응답 형식, true: 상세정보 응답
  }
}

#특정 정보 요청 (배열 형태)
{
  "active_streams": [
    "clients",  # 현재 연결된 클라이언트 수 (뷰어+입력+출력)
    "viewers",  # 현재 뷰어 수
    "inputs",   # 현재 입력 개수
    "outputs"   # 현재 출력 개수
  ]
}

#정보 요청 참고
{
  "active_streams": [
    #Array of string values of stream properties that are to be retrieved. 
    #Possible options are:
    "clients", #Current count of connected clients (viewers+inputs+outputs)
    "lastms", #Newest/last (currently) available timestamp in milliseconds
    "firstms", #Oldest/first requestable timestamp in milliseconds
    "viewers", #Current viewers count
    "inputs", #Current inputs count
    "outputs", #Current outputs count
    "views", #Total viewer session count since stream start
    "viewseconds", #Total sum of seconds watched by viewers since stream start
    "upbytes", #Total bytes uploaded since stream start
    "downbytes", #Total bytes downloaded since stream start
    "packsent", #Total packets sent since stream start
    "packloss", #Total packets lost since stream start
    "packretrans", #Total packets retransmitted since stream start
    "zerounix", #Unix time in seconds of timestamp epoch (zero point), if known
    "health", #Stream health object, identical to payload of STREAM_BUFFER health data
    "tracks", #Count of currently valid tracks in this stream
    "status" #Current stream status in human readable format
  ]
}

# 응답 JSON 예시 : 기본
{
  "LTS": 1,
  "active_streams": [
    "stream02"
  ],
  "authorize": {
    "status": "OK"
  }
}

#응답 JSON 예시 :  특정 정보 요청 (배열 형태)
{
  "LTS": 1,
  "active_streams": {
    "stream02": [
      2,
      1,
      1,
      0
    ]
  },
  "authorize": {
    "status": "OK"
  }
}

 

 

7. 스트림 통계 조회: stats_streams

최근 약 10분 동안 통계를 가지고 있는 스트림 목록을 요청하는 API입니다.

현재 실행 중인 스트림만이 아니라, 최근 10분 내에 실행된 스트림도 포함됩니다.

즉, 완전히 종료된 스트림이라도 최근 10분 동안 활성화되었다면 통계를 확인할 수 있습니다.

일시적인 스트림이나 와일드카드(*) 기반의 스트림도 포함됩니다.

#요청문 Python 코드
#최근 10분 동안 통계가 있는 모든 스트림의 목록만 반환
import requests
url = "http://192.168.1.70:4242/api2"
payload = {
    "authorize": {
        "username": "user_d",
        "password": "8053fbe0ddd8159f000bb03eaf9853d0"
    },
    "state_streams": 1
}
headers = {"content-type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.json())


#특정 정보 요청
{
  "stats_streams": [
    "clients", // 현재 연결된 클라이언트 수 (뷰어+입력+출력)
    "lastms"   // 현재 라이브 스트림의 최신 타임스탬프 (VoD는 항상 0)
  ]
}


#응답 JSON 예시 : 기본
{
  "LTS": 1,
  "authorize": {
    "status": "OK"
  },
  "stats_streams": [
    "",
    "stream02"
  ]
}

#응답 JSON 예시 : 특정 정보 요청
{
  "LTS": 1,
  "authorize": {
    "status": "OK"
  },
  "stats_streams": {
    "": [
      2,
      -1
    ]
  }
}

 

 

8. 스트림 세션 강제 종료: stop_sessions

특정 스트림 이름 또는 프로토콜을 사용하는 세션을 강제 종료하는 기능을 합니다.

해당 스트림을 시청 중인 모든 사용자 세션이 즉시 종료됩니다.

해당 프로토콜을 사용하는 모든 연결(입력/출력)이 강제로 끊깁니다.

세션이 종료되면, 기존에 열려 있던 모든 연결(input/output)이 즉시 차단됩니다.

#요청문 Python 코드
import requests
url = "http://192.168.1.70:4242/api2"
payload = {
    "authorize": {
        "username": "user_id",
        "password": "8053fbe0ddd8159f000bb03eaf9853d0"
    },
    "stop_sessions": "rose"
}
headers = {"content-type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.json())

#응답 JSON 예시
{
  "LTS": 1,
  "authorize": {
    "status": "OK"
  }
}

##########################################
# "rose" 스트림의 "RTSP" protocol를 사용하는 session을 제거
"stop_sessions":{
   "rose":"RTSP"
 }
##########################################
# 다수 session을 제거하는 방법
# "rose" 스트림의 "RTMP" protocol을 사용하는 session을 제거
# ""(모든) 스트림의 "RTSP" protocol을 사용하는 session을 제거
"stop_sessions":{
  "rose": "RTMP",
   "" : "RTSP"
}
########################################
#아래 코드는 수행 실패함
{
  "stop_sessions": [
    "rose"
  ]
}

 

관련 글 링크

7. MistServer API 인증 방식 및 주요 API 이해

https://docs.mistserver.org/category/list-of-api-calls/

 

List of API calls | MistServer documentation

Below is a detailed list of all available API calls available in MistServer.

docs.mistserver.org

 

728x90