ogg를 스트리밍 하려고 합니다...

맹고이의 이미지

파이썬으로 간단한 스트리밍 서버를 만들어 보고 있습니다.

rtp를 이용하는 건 아니구요...

http로 쏘아주면 WinAmp나 XMMS같은 프로그램이 재생해주는 겁니다.

mp3 파일은 아래 소스처럼 단순 무식하게 제가 정한 사이즈 만큼 보내고

bitrate로 시간을 계산하니 재생이 잘 되는데요.

    161 class MP3Meter(Meter):
    162         def __init__(self, handle, path, timer, read_size):
    163                 Meter.__init__(self, timer)
    164                 self.handle = handle
    165                 self.read_size = read_size
    166
    167                 info = fileinfo.FileInfo(path)
    168                 bitrate = info.bitrate
    169                 self.byterate = float(bitrate * 1024) / 8
    170
    171         def read(self):
    172                 self.real_time = time.time() - self.start_time
    173
    174                 data = self.handle.read(self.read_size)
    175                 data_time_segment = (float(len(data)) / self.byterate)
    176                 self.data_time = self.data_time + data_time_segment
    177
    178                 return data

ogg는 저렇게 보내니까 WinAmp가 재생을 못하네요.

ogg 포멧에 관한 지식이 없다보니... ;

어떤식으로 보내면 되는지 관련 자료나 조언 부탁드립니다.

P.S. 시간 되시면 http://kldp.net/projects/moss 에서 소스를 봐주세요. 8)

sjpark의 이미지

ogg던 mp3던

HTTP를 사용하신다면,

HTTP 헤더정보에 어떤 파일을 보내는지 정보를 넣어주고

쭉쭉 뿌려 주면, 클라이언트가 적당히 헤더를 보고 파일 종류 알아내서

연주하지 않나요?

물론 OGG를 해보진 않았지만, MP3같은 경우는 그냥 되더군요.

비트레이트 같은거 생각안해도 bitrate도 알아서 잘 잡아주더군요(클라이언트에서)

다만 OGG같은 경우에는 클라이언트에 OGG용 드라이버가 설치되어 있어야 할텐데요.

맹고이의 이미지

sjpark wrote:
ogg던 mp3던

HTTP를 사용하신다면,

HTTP 헤더정보에 어떤 파일을 보내는지 정보를 넣어주고

쭉쭉 뿌려 주면, 클라이언트가 적당히 헤더를 보고 파일 종류 알아내서

연주하지 않나요?

물론 OGG를 해보진 않았지만, MP3같은 경우는 그냥 되더군요.

비트레이트 같은거 생각안해도 bitrate도 알아서 잘 잡아주더군요(클라이언트에서)

다만 OGG같은 경우에는 클라이언트에 OGG용 드라이버가 설치되어 있어야 할텐데요.

답변 감사합니다. 쭉쭉 보냈는데 재생이 안되서 질문을 드리고 있습니다.

헤더는 "HTTP/1.0 200 OK\nContent-Type: audio/x-ogg\n\n"

이렇게 보냈는데 뭔가 부족한 게 있는 건가요?

mp3 파일은 "HTTP/1.0 200 OK\nContent-Type: audio/mpeg\n\n"

이렇게 보냈는데 재생이 잘 됩니다.

그리고 bitrate는 클라이언트를 위해서가 아니라 실시간 재생시 현재 재생 위치를 구하기 위해 사용하고 있구요.

WinAmp로 로컬에서 ogg 파일을 재생하니 잘 나옵니다.

liongo의 이미지

사용해보려니

import ogg.vorbis

패키지가 없군요.. ㅜ.ㅜ

찾아보니 몇군대 나오는데 뭔지 일일이 받긴 그렇고

알려주시면 해보겠습니다..

' 형식이 내용을 규정한다. '

맹고이의 이미지

liongo wrote:
사용해보려니

import ogg.vorbis

패키지가 없군요.. ㅜ.ㅜ

찾아보니 몇군대 나오는데 뭔지 일일이 받긴 그렇고

알려주시면 해보겠습니다..

http://www.andrewchatham.com/pyogg/

ogg.vorbis 모듈은 여기에 있는 것을 사용하였습니다.

다양한 기능이 있는 모듈 같은데 지식이 부족해서 간단한 곳에서 밖에 쓰지 않고

있습니다. 그리고 제 프로젝트 CVS에 있는 놈은 ogg 파일을 만나면

그냥 다음 곡으로 넘어가게 해놔서 테스트 해주실려면

live.py의 OGGMeter class를 수정하면 될 겁니다.

여기에서도 도와주시니 감사합니다. 8)

liongo의 이미지

설치완료 실행완료

moss.conf에 web 방식으로 설정 하고..

테스트 플레이 잘됩니다..

DEEP_Purple - Smoke On The Water 듣고있구요 ㅡㅡa

ogg파일이구요.. WinAmp에서 제생중입니다.

윈엠프버젼 ver.2.80입니다..

제가 테스트를 잘못햇는지몰라도..

live mode로 테스트해야되나요?

ogg패키지 깔기 전에안되서 ogg template구성관련 exception발생부분

처리만 했는데.. 패키없을때 쫑나는부분만 했눈데...

p.s

도와드리다니 과분한소리 하지마세용 저야말로 흥미, 재밌게 보구있습니다.

' 형식이 내용을 규정한다. '

맹고이의 이미지

하핫, 네 web 모드는 잘되고 있었습니다.

패킷 쏘아주는 건 별다른 차이가 없는 것 같은데

live 모드가 안되네요. ^^;

liongo의 이미지

shoucast를 보니 MP3 or MPEG 방식을 쓰네요..

OGG를 데이터를 MP3 또는 MPEG로 변환해서 하는방법으로..

해보심이.. Winamp가 스트리밍을 ogg로 받아주는지 명확하게

모르겠습니다.. OGG를 윈엠프로 Shoutcast로 방송을하니..

변환이 되는것같네요.

' 형식이 내용을 규정한다. '

Prentice의 이미지

맹고이 wrote:
헤더는 "HTTP/1.0 200 OK\nContent-Type: audio/x-ogg\n\n"

이렇게 보냈는데 뭔가 부족한 게 있는 건가요?

http://my.netian.com/~cajunlee/vorbis/vorbisfaq.htm#mimetype

오그 보비스의 MIME 타입은 audio/x-ogg가 아니라 application/ogg입니다. 공식 mimetype입니다.

liongo wrote:
OGG를 윈엠프로 Shoutcast로 방송을하니..

변환이 되는것같네요.


SHOUTcast의 경우 소리를 mp3로 압축해서 보내는 방식을 사용합니다. 재압축을 하는 것 보다는 ezstream 등의 방법으로 그냥 http 스트리밍을 하시는 편이 나을 것입니다.
맹고이의 이미지

답변 감사합니다.

질문에는 적지 않았지만 MIME 타입을

"application/x-ogg", "application/ogg"도 해보았습니다.

그리고 방금 간단하게 테스트를 해보았는데요.

아래처럼 무식하게 쏘아주었을 때, 윈앰프가 MP3는 재생을 하는데 OGG가 재생이 안됩니다.

알려주신 ezstream 소스는 아직 보지 않아서 질문을 드립니다만...

OGG는 그냥 HTTP 헤더에 MIME 타입을 지정하고 보내면 재생이 안되는 건가요?

에고... 좀 더 공부를 해야겠습니다. ^^;

import socket
import SocketServer

class CommonServer(SocketServer.ThreadingTCPServer):
    def server_bind(self):
        SocketServer.TCPServer.server_bind(self)
        host, port = self.socket.getsockname()

        if not host or host == '0.0.0.0':
            host = socket.gethostname()
            hostname, hostnames, hostaddrs = socket.gethostbyaddr(host)

        if '.' not in hostname:
            for host in hostnames:
                if '.' in host:
                    hostname = host
                    break
        self.server_name = hostname
        self.server_port = port


class CommonRequestHandler(SocketServer.StreamRequestHandler):
    def handle(self):
        # fp = open("/home/myunggoni/music/OGG/a.ogg", "rb")
        # self.wfile.write('HTTP/1.0 200 OK\nContent-Type: application/ogg\n\n')

        fp = open("/home/myunggoni/music/tomorrow.mp3", "rb")
        self.wfile.write('HTTP/1.0 200 OK\nContent-Type: audio/mpeg\n\n')

        while 1:
                data = fp.read(8192)
                self.wfile.write(data)

    def setup(self):
        SocketServer.StreamRequestHandler.setup(self)

def test():
    portnum = 9999
    comserver = CommonServer(('', portnum), CommonRequestHandler)
    comserver.serve_forever()


if __name__ == '__main__':
    test()
맹고이의 이미지

엇... 알아냈습니다. ^^;

윈앰프에 Ctrl+X를 눌러서 url을 입력할 때

http://dummy-host.example.com:9999/

하니까 재생이 안되고 파일이 존재하던 안하던

http://dummy-host.example.com:9999/foo.ogg

라고 ogg 확장자를 명시해줘야 재생이 되네요.

이건 윈앰프 자체의 문제가 아닌지... 으윽...

삽질했습니다. -_-;

liongo의 이미지

뜨어어~~

대략난감하군요 ㅋㅋ

' 형식이 내용을 규정한다. '

hiseob의 이미지

압축 파일 프로그램의 경우에는

RAR 파일을 ARJ 로 확장명을 바꾸고,

윈RAR 로 읽으면 RAR 로 인식 됩니다.

하지만 윈앰프는 이런게 안되더군요.

OGG 파일을 확장명을 없애거나 MP3 로 해놓으면 절대 인식 안됩니다.

윈앰프가 아무래도 MP3 가 주 종목 이다보니 MP3 기준으로 해석 하는것 같은데요 ^^;;

그래서 샤우트 캐스트도 재압축 을 하지 않을까 생각 합니다.

Prentice의 이미지

hiseob wrote:
윈앰프가 아무래도 MP3 가 주 종목 이다보니 MP3 기준으로 해석 하는것 같은데요 ^^;;

그래서 샤우트 캐스트도 재압축 을 하지 않을까 생각 합니다.


재압축이 이루어지는 이유는 SHOUTcast 방송 플러그인인 dsp_shoutcast.dll이 mp3 압축 플러그인이기 때문에 그렇습니다.. ^^;

dsp_oddcast등을 사용하시면 오그로 압축해서 방송을 하실 수 있습니다.

맹고이의 이미지

ogg라는 포멧이 아깝긴 하지만...

mp3로 변환해서 재생하는 방법을 알아봐야겠네요... ;

혹시나 ogg를 mp3로 변환하는 소스나 관련 자료를 알고 계시면

가르쳐 주세요. 이왕이면 파이썬으로 되어있으면 좋겠지만... ^^;

살짝 찾아봤는데 ogg로 변환하는 건 많이 보이네요. ;

혹시 mp3로 변환하려면 wav로 변환한 뒤에 다시 변환해야하는 건가요?

아무래도 이번 기회에 encode/decode에 관해서 공부해야겠습니다.

liongo의 이미지

맹고이님 제가 해봤는데 성공했습니다..

참 여러 답변을 조합해서 답을 알아내는군요 ㅡㅡa

live로 재생할때 문제가 모냐면요..

중간에 붙어서 들어갈경우.. 헤더정보가 없이 중간데이터부터

받으면 ogg가 재생이 안되는군요

그래서 제가 처음 접속할때 현재 재생중이 ogg파일의 헤더를

맨처음 보내준후 현재 재생중인 data를 보내주니 현재지점부터

재생이 되는군요 휴우 저도 구경하다 심마에 빠져서 삽질했습니다 ㅡㅡa

live로 음악나오는데 이 쾌감 이래서 프로그래머를 계속하나봅니다..

그럼 대략즐.. 지금이 9신데 업무보고 하랍니다 ㅜ.ㅜ

p.s 맹고이님 상주세요 ㅋㅋ

' 형식이 내용을 규정한다. '

Prentice의 이미지

오그 방송 관련 소스라면 다음의 장소에서 찾아보실 수 있습니다.

http://www.icecast.org/
http://www.icecast.org/3rdparty.php

icecast가 어떻게 생방송을 처리하는지를 보시면 도움이 될지도 모르겠습니다.

liongo님 말씀대로 오그 보비스의 경우 헤더에 디코딩 코드북등이 들어있기 때문에 (파일마다 코드북이 서로 다를 수 있기 때문에 그렇습니다.) 중간에 끼어드는 청취자에게는 헤더를 반드시 보내줘야 합니다.

맹고이의 이미지

오옷~ 두분 모두 답변 감사드립니다!!

반드시 ogg 헤더를 보내주고 데이터를 보내줘야 되는군요... 8)

링크해주신 소스 잘 참고하겠습니다.

그리고 liongo님, 어느 부분을 어떻게 고쳤는지...

여기 게시판이나 프로젝트 게시판에 알려주시면 더욱 더 감사하겠습니다. :o

p.s. 하핫, 상은 무엇을 드려야 될지 모르겠네요~

프로젝트 관심있게 봐주셔서 감사합니다. ^^;

liongo의 이미지

프로젝트 게시판에 올려놨습니다..

이미 고치셨겠지만 혹시나해서...

그럼 잘만들어주세요 ^^;;

' 형식이 내용을 규정한다. '

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.