diff --git a/README.md b/README.md index 3fea710..2e9f591 100644 --- a/README.md +++ b/README.md @@ -15,10 +15,14 @@ Go Library and command line tool for working with cheap action cameras. Supplying no additional command will start streaming a preview video stream to your local system. To view the video use the `camera.sdp` file and open it in a compatible player like VLC. -The stream is a RTP stream sent to Port 5220 on localhost containing H.264 data in preview resolution as AVP Type 99. +The stream is a RTP stream sent to Port 5220 on localhost containing H.264 data in preview resolution as AVP Type 99. Additionally it is possible to start a crude RTSP-Server that is able to serve a single client. ``` +# Start preview streaming via RTP actioncam + +# Start RTSP server and stream preview to connecting +actioncam rtsp ``` ### Shooting a still picture diff --git a/actioncam.go b/actioncam.go index 85af090..aaf2f6a 100644 --- a/actioncam.go +++ b/actioncam.go @@ -46,6 +46,12 @@ func main() { bufio.NewReader(os.Stdin).ReadBytes('\n') }, + PreRun: func(cmd *cobra.Command, args []string) { + camera = connectAndLogin(net.ParseIP(args[0]), int(port), username, password, verbose) + }, + PostRun: func(cmd *cobra.Command, args []string) { + camera.Disconnect() + }, } rootCmd.PersistentFlags().Int16VarP(&port, "port", "P", 6666, "Specify an alternative camera port to connect to") diff --git a/rtsp/RTSPServer.go b/rtsp/RTSPServer.go index 52bff62..c596d2a 100644 --- a/rtsp/RTSPServer.go +++ b/rtsp/RTSPServer.go @@ -2,6 +2,7 @@ package rtsp import ( "bufio" + "crypto/md5" "fmt" "log" "net" @@ -92,6 +93,8 @@ func (s *Server) handleRequest(packet []string, conn net.Conn) { } } + session := fmt.Sprintf("%X", md5.Sum([]byte(conn.RemoteAddr().String()))) + switch method { case "OPTIONS": writeStatus(conn, 200, "OK") @@ -119,7 +122,7 @@ func (s *Server) handleRequest(packet []string, conn net.Conn) { writeStatus(conn, 200, "OK") replyCSeq(conn, headers) writeHeader(conn, "Transport", headers["Transport"]+";ssrc=0") - writeHeader(conn, "Session", "1") + writeHeader(conn, "Session", session) conn.Write([]byte("\r\n")) case "PLAY": @@ -128,7 +131,7 @@ func (s *Server) handleRequest(packet []string, conn net.Conn) { writeStatus(conn, 200, "OK") replyCSeq(conn, headers) - writeHeader(conn, "Session", "1") + writeHeader(conn, "Session", session) writeHeader(conn, "RTP-Info", "url="+request[1]+";seq=0;rtptime=0") conn.Write([]byte("\r\n")) case "TEARDOWN": @@ -136,6 +139,14 @@ func (s *Server) handleRequest(packet []string, conn net.Conn) { writeStatus(conn, 200, "OK") replyCSeq(conn, headers) conn.Write([]byte("\r\n")) + case "RECORD": + s.camera.StartRecording() + + writeStatus(conn, 200, "OK") + replyCSeq(conn, headers) + writeHeader(conn, "Session", session) + conn.Write([]byte("\r\n")) + default: return }