Container
NuFiStreamer가 설치된 도커 이미지를 이용하여 컨테이너를 띄우고 접근해봅니다.
Goal
- NufiStreamer가 설치된 컨테이너 실행하기
- 실행한 컨테이너 환경에서 제공된 example code 실행하기
NufiStreamer가 설치된 컨테이너 실행하기
NuFiStreamer가 설치된 이미지로 컨테이너 환경 설정 및 접속합니다.
1. NuFiStreamer Image를 pull합니다.
# amd64
docker pull registry.gocap.kr/nufi/nufilibrary:0.1.5
# arm64
docker pull registry.gocap.kr/nufi/nufilibrary:0.1.5-arm64
2. NuFiStreamer Container를 실행합니다.
# amd64
docker run -it --rm registry.gocap.kr/nufi/nufilibrary:0.1.5 /bin/bash
# arm64
docker run -it --rm registry.gocap.kr/nufi/nufilibrary:0.1.5-arm64 /bin/bash
- 로컬 환경에 존재하는 처리할 비디오 관련 데이터를 컨테이너에 넣으려면 아래 command를 이용하세요.
# amd64
docker run -it --rm -v <로컬 데이터 dir path>:<마운트할 컨테이너 내부 path> registry.gocap.kr/nufi/nufilibrary:0.1.4 /bin/bash
# arm64
docker run -it --rm -v <로컬 데이터 dir path>:<마운트할 컨테이너 내부 path> registry.gocap.kr/nufi/nufilibrary:0.1.4-arm64 /bin/bash
3. Pipeline example code 실행하여 환경설정이 여부를 확인합니다.
- video_path와 결과를 저장할 result_file_path를 argument로 넣어 run_sdstreamer 함수를 실행해봅니다.
import logging as log
import os
import sys
from gi.repository import GLib, Gst
import nufi
from nufi.models import Yolo, BaseModel
nufi.init()
def bus_call(_, message, loop):
t = message.type
if t == Gst.MessageType.EOS:
log.info("End-of-stream")
loop.quit()
elif t == Gst.MessageType.WARNING:
err, debug = message.parse_warning()
log.warning("Warning: %s: %s", err, debug)
elif t == Gst.MessageType.ERROR:
err, debug = message.parse_error()
log.error("Error: %s: %s", err, debug)
loop.quit()
return True
def run_sdstreamer(video_path, result_file_path):
# 1. Elements 생성
filesrc = Gst.ElementFactory.make("filesrc", "filesrc")
decodebin = Gst.ElementFactory.make("decodebin", "decodebin")
videoconvert1 = Gst.ElementFactory.make("videoconvert", "videoconvert1")
queue = Gst.ElementFactory.make("queue", "queue")
# - nufi element 생성
nufi = Gst.ElementFactory.make("nufi", "yolo")
draw = Gst.ElementFactory.make("draw", "draw")
qos = Gst.ElementFactory.make("qos", "qos")
videoconvert2 = Gst.ElementFactory.make("videoconvert", "videoconvert2")
x264enc = Gst.ElementFactory.make("x264enc", "x264enc")
mp4mux = Gst.ElementFactory.make("mp4mux", "mp4mux")
sink = Gst.ElementFactory.make("filesink", "filesink")
elements = [
filesrc,
decodebin,
videoconvert1,
queue,
nufi,
draw,
qos,
videoconvert2,
x264enc,
mp4mux,
sink,
]
if not all(elements):
log.error("Unable to create Elements")
sys.exit(-1)
# 2. Elements properties 설정
filesrc.set_property("location", video_path)
videoconvert1.set_property("n-threads", 16)
videoconvert2.set_property("n-threads", 16)
sink.set_property("location", result_file_path)
# - nufi element models 설정
models = [Yolo() for _ in range(6)] # for using nufi element multi threading
nufi.set_property("model", models)
# 3. 파이프라인 생성
pipeline = Gst.Pipeline()
pipeline.add(*elements)
for i in range(len(elements) - 1):
if elements[i].name != "decodebin":
if not Gst.Element.link(elements[i], elements[i + 1]):
log.error(
"Elements %s and %s could not be linked.",
elements[i].get_name(),
elements[i + 1].get_name(),
)
sys.exit(-1)
loop = GLib.MainLoop()
bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect("message", bus_call, loop)
def on_demuxer_pad_added(_, pad):
if not pad.has_current_caps():
log.error("Pad %s has no caps, can't link", pad.get_name())
sys.exit(-1)
caps = pad.get_current_caps()
struct = caps.get_structure(0)
if struct.get_name().startswith("video"):
pad.link(videoconvert1.get_static_pad("sink"))
decodebin.connect("pad-added", on_demuxer_pad_added)
# 4. 파이프라인 시작
ret = pipeline.set_state(Gst.State.PLAYING)
if ret == Gst.StateChangeReturn.FAILURE:
log.error("Unable to set the pipeline to the playing state.")
sys.exit(-1)
try:
loop.run()
except Exception as e:
log.error("App finished : %s", e)
loop.quit()
pipeline.set_state(Gst.State.NULL)
return result_file_path