Skip to content

Instantly share code, notes, and snippets.

@02strich
Created March 19, 2014 17:50
Show Gist options
  • Save 02strich/9647337 to your computer and use it in GitHub Desktop.
Save 02strich/9647337 to your computer and use it in GitHub Desktop.
import socket
import random
IP = "192.168.178.2"
SID = random.randint(0,10000)
CSEQ = 0
class RtspSession(object):
def __init__(self, remote):
self.client_id = random.randint(0,10000)
self.req_id = 1
self.session_id = None
self.server_ip = remote
self.server_port = None
self.ss = None
# connect
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.connect((remote, 5000))
# do RTSP stuff
AnnounceRequest(self).send()
# extract server config
r = SetupRequest(self)
r.send()
self.session_id = r.session_id
for transport_option in r.transport_options:
if transport_option.startswith("server_port"):
self.server_port = int(transport_option[12:])
RecordRequest(self).send()
def connect_stream(self):
if self.server_port is None:
return
self.ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.ss.connect((self.server_ip, self.server_port))
def close(self):
if not self.ss is None:
self.ss.close()
self.s.close()
def volume(self, volume_val):
SetParameterRequest(self, {"volume": volume_val}).send()
def send_sample(self, samples):
print "blub: " + str(len(samples))
header = "\x24\x00\x05\x8c\xF0\xFF\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
data = header + samples
self.ss.sendall(data)
class RtspRequest(object):
method = None
def __init__(self, session):
self.headers = {}
self.session = session
def send(self):
# get body
body = self.render_body()
# command line & mandatory headers
data = "%s rtsp://%s/%s RTSP/1.0\r\nCSeq: %d\r\nUser-Agent: iTunes/4.6 (Macintosh; U; PPC Mac OS X 10.3)\r\n" % (self.method, self.session.s.getpeername()[0], self.session.client_id, self.session.req_id)
# body length header
if body:
self.headers["Content-Length"] = len(body)
# other headers
for k,v in self.headers.iteritems():
data += "%s: %s\r\n" % (k,v)
data += "\r\n"
# data
if body:
data += body
# send & receive
self.session.s.sendall(data)
response = self.session.s.recv(1000)
# increment sequence
self.session.req_id += 1
# parse response
self.parse_response(response)
print "-------------"
print data
print "-------------"
print response
def render_body(self):
pass
def parse_response(self, response):
pass
class AnnounceRequest(RtspRequest):
method = "ANNOUNCE"
def __init__(self, session):
super(AnnounceRequest, self).__init__(session)
self.headers["Content-Type"] = "application/sdp"
def render_body(self):
return """v=0\r\no=iTunes %s 0 IN IP4 %s\r\ns=iTunes\r\nc=IN IP4 %s\r\nt=0 0\r\nm=audio 0 RTP/AVP 96\r\na=rtpmap:96 AppleLossless\r\na=fmtp:96 352 0 16 40 10 14 2 255 0 0 44100\r\n""" % (self.session.client_id, self.session.s.getpeername()[0], self.session.s.getsockname()[0])
class SetupRequest(RtspRequest):
method = "SETUP"
def __init__(self, session):
super(SetupRequest, self).__init__(session)
self.headers["Transport"] = "RTP/AVP/UDP;unicast;interleaved=0-1;mode=record"
def parse_response(self, response):
self.session_id = None
for line in response.split("\r\n"):
# extract session ID
if line.startswith("Session: "):
self.session_id = line[9:]
# extract transport options
if line.startswith("Transport: "):
self.transport_options = line[11:].split(";")
class RecordRequest(RtspRequest):
method = "RECORD"
def __init__(self, session):
super(RecordRequest, self).__init__(session)
self.headers["Range"] = 'npt=0-'
self.headers['RTP-Info'] = "seq=0;rtptime=0"
self.headers['Session'] = self.session.session_id
class SetParameterRequest(RtspRequest):
method = "SET_PARAMETER"
def __init__(self, session, opts):
super(SetParameterRequest, self).__init__(session)
self.opts = opts
self.headers["Content-Type"] = 'text/parameters'
self.headers["Session"] = self.session.session_id
def render_body(self):
data = ""
for k, v in self.opts.iteritems():
data += "%s: %s\r\n" % (k,v)
return data
session = RtspSession(IP)
session.volume("-10.0")
session.connect_stream()
with open("test.data", "rb") as f:
data = f.read(352 * 2 * 2)
while len(data) == 352 * 2 * 2:
session.send_sample(data)
data = f.read(352 * 2 * 2)
session.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment