Added Auto-Discovery through UDP Broadcasts
This commit is contained in:
parent
6451deea33
commit
6570ac93c0
2 changed files with 135 additions and 18 deletions
80
actioncam.go
80
actioncam.go
|
|
@ -42,7 +42,7 @@ func main() {
|
|||
var rootCmd = &cobra.Command{
|
||||
Use: "ipcamera [Cameras IP Address]",
|
||||
Short: "ipcamera is a tool to stream the video preview of cheap action cameras without the mobile application",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
defer camera.Disconnect()
|
||||
relay := libipcamera.CreateRTPRelay(net.ParseIP("127.0.0.1"), 5220)
|
||||
|
|
@ -66,7 +66,11 @@ func main() {
|
|||
}
|
||||
},
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
camera = connectAndLogin(discoverCamera(verbose), int(port), username, password, verbose)
|
||||
} else {
|
||||
camera = connectAndLogin(net.ParseIP(args[0]), int(port), username, password, verbose)
|
||||
}
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
camera.Disconnect()
|
||||
|
|
@ -103,7 +107,7 @@ func main() {
|
|||
var ls = &cobra.Command{
|
||||
Use: "ls [Cameras IP Address]",
|
||||
Short: "List files stored on the cameras SD-Card",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
files, err := camera.GetFileList()
|
||||
if err != nil {
|
||||
|
|
@ -116,22 +120,44 @@ func main() {
|
|||
}
|
||||
},
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
camera = connectAndLogin(discoverCamera(verbose), int(port), username, password, verbose)
|
||||
} else {
|
||||
camera = connectAndLogin(net.ParseIP(args[0]), int(port), username, password, verbose)
|
||||
}
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
camera.Disconnect()
|
||||
},
|
||||
}
|
||||
|
||||
var discover = &cobra.Command{
|
||||
Use: "discover",
|
||||
Short: "Try to discover a camera by sending UDP broadcasts",
|
||||
Args: cobra.MaximumNArgs(0),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cameraIP, err := libipcamera.AutodiscoverCamera(verbose)
|
||||
if err != nil {
|
||||
log.Printf("ERROR Discovering Camera: %s\n", err)
|
||||
}
|
||||
|
||||
log.Printf("Found Camera: %+v\n", cameraIP)
|
||||
},
|
||||
}
|
||||
|
||||
var still = &cobra.Command{
|
||||
Use: "still [Cameras IP Address]",
|
||||
Short: "Take a still image and save to SD-Card",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
camera.TakePicture()
|
||||
},
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
camera = connectAndLogin(discoverCamera(verbose), int(port), username, password, verbose)
|
||||
} else {
|
||||
camera = connectAndLogin(net.ParseIP(args[0]), int(port), username, password, verbose)
|
||||
}
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
camera.Disconnect()
|
||||
|
|
@ -141,12 +167,16 @@ func main() {
|
|||
var record = &cobra.Command{
|
||||
Use: "record [Cameras IP Address]",
|
||||
Short: "Start recording video to SD-Card",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
camera.StartRecording()
|
||||
},
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
camera = connectAndLogin(discoverCamera(verbose), int(port), username, password, verbose)
|
||||
} else {
|
||||
camera = connectAndLogin(net.ParseIP(args[0]), int(port), username, password, verbose)
|
||||
}
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
camera.Disconnect()
|
||||
|
|
@ -156,12 +186,16 @@ func main() {
|
|||
var stop = &cobra.Command{
|
||||
Use: "stop [Cameras IP Address]",
|
||||
Short: "Stop recording video to SD-Card",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
camera.StopRecording()
|
||||
},
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
camera = connectAndLogin(discoverCamera(verbose), int(port), username, password, verbose)
|
||||
} else {
|
||||
camera = connectAndLogin(net.ParseIP(args[0]), int(port), username, password, verbose)
|
||||
}
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
camera.Disconnect()
|
||||
|
|
@ -171,7 +205,7 @@ func main() {
|
|||
var firmware = &cobra.Command{
|
||||
Use: "firmware [Cameras IP Address]",
|
||||
Short: "Retrieve firmware version information from the camera",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
firmware, err := camera.GetFirmwareInfo()
|
||||
if err != nil {
|
||||
|
|
@ -181,7 +215,11 @@ func main() {
|
|||
log.Printf("Firmware Version: %s\n", firmware)
|
||||
},
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
camera = connectAndLogin(discoverCamera(verbose), int(port), username, password, verbose)
|
||||
} else {
|
||||
camera = connectAndLogin(net.ParseIP(args[0]), int(port), username, password, verbose)
|
||||
}
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
camera.Disconnect()
|
||||
|
|
@ -191,7 +229,7 @@ func main() {
|
|||
var rtsp = &cobra.Command{
|
||||
Use: "rtsp [Cameras IP Address]",
|
||||
Short: "Start an RTSP-Server serving the cameras preview.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
rtspServer := rtsp.CreateServer("127.0.0.1", 8554, camera)
|
||||
|
|
@ -203,7 +241,11 @@ func main() {
|
|||
}
|
||||
},
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
camera = connectAndLogin(discoverCamera(verbose), int(port), username, password, verbose)
|
||||
} else {
|
||||
camera = connectAndLogin(net.ParseIP(args[0]), int(port), username, password, verbose)
|
||||
}
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
camera.Disconnect()
|
||||
|
|
@ -213,7 +255,7 @@ func main() {
|
|||
var cmd = &cobra.Command{
|
||||
Use: "cmd [RAW Command] [Cameras IP Address]",
|
||||
Short: "Send a raw command to the camera",
|
||||
Args: cobra.ExactArgs(2),
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
command, err := hex.DecodeString(args[0])
|
||||
if err != nil {
|
||||
|
|
@ -233,7 +275,11 @@ func main() {
|
|||
bufio.NewReader(os.Stdin).ReadBytes('\n')
|
||||
},
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) != 2 {
|
||||
camera = connectAndLogin(discoverCamera(verbose), int(port), username, password, verbose)
|
||||
} else {
|
||||
camera = connectAndLogin(net.ParseIP(args[1]), int(port), username, password, verbose)
|
||||
}
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
camera.Disconnect()
|
||||
|
|
@ -243,7 +289,7 @@ func main() {
|
|||
var fetch = &cobra.Command{
|
||||
Use: "fetch [Cameras IP Address]",
|
||||
Short: "List files stored on the cameras SD-Card",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
files, err := camera.GetFileList()
|
||||
if err != nil {
|
||||
|
|
@ -257,7 +303,11 @@ func main() {
|
|||
downloadFile(filepath.Base(newestFile), url)
|
||||
},
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if len(args) == 0 {
|
||||
camera = connectAndLogin(discoverCamera(verbose), int(port), username, password, verbose)
|
||||
} else {
|
||||
camera = connectAndLogin(net.ParseIP(args[0]), int(port), username, password, verbose)
|
||||
}
|
||||
},
|
||||
PostRun: func(cmd *cobra.Command, args []string) {
|
||||
camera.Disconnect()
|
||||
|
|
@ -272,6 +322,7 @@ func main() {
|
|||
rootCmd.AddCommand(record)
|
||||
rootCmd.AddCommand(firmware)
|
||||
rootCmd.AddCommand(rtsp)
|
||||
rootCmd.AddCommand(discover)
|
||||
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
log.Println(err)
|
||||
|
|
@ -299,3 +350,14 @@ func downloadFile(filepath string, url string) error {
|
|||
_, err = io.Copy(out, resp.Body)
|
||||
return err
|
||||
}
|
||||
|
||||
func discoverCamera(verbose bool) net.IP {
|
||||
cameraIP, err := libipcamera.AutodiscoverCamera(verbose)
|
||||
if err != nil {
|
||||
log.Printf("ERROR during Autodiscover: %s\n", err)
|
||||
}
|
||||
if verbose {
|
||||
log.Printf("Found Camera: %s\n", cameraIP)
|
||||
}
|
||||
return cameraIP
|
||||
}
|
||||
|
|
|
|||
55
libipcamera/Discovery.go
Normal file
55
libipcamera/Discovery.go
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
package libipcamera
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Ports to try discovery on
|
||||
var targetPorts = []int{22600, 21600}
|
||||
|
||||
// AutodiscoverCamera will try to find a camera using UDP Broadcasts
|
||||
func AutodiscoverCamera(verbose bool) (net.IP, error) {
|
||||
conn, err := net.ListenPacket("udp", ":22601")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
for _, port := range targetPorts {
|
||||
go sendDiscoveryBroadcasts(conn, port, 5, verbose)
|
||||
}
|
||||
|
||||
buffer := make([]byte, 80)
|
||||
_, remoteAddr, err := conn.ReadFrom(buffer)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
udpAddr := remoteAddr.(*net.UDPAddr)
|
||||
return udpAddr.IP, nil
|
||||
}
|
||||
|
||||
func sendDiscoveryBroadcasts(localConn net.PacketConn, port, count int, verbose bool) {
|
||||
broadcastAddress, err := net.ResolveUDPAddr("udp", fmt.Sprintf("255.255.255.255:%d", port))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
broadcastPacket := CreateCommandPacket(0x0114)
|
||||
|
||||
if verbose {
|
||||
log.Printf("Trying Autodiscovery using UDP Port %d\n", port)
|
||||
}
|
||||
for i := 0; i < count; i++ {
|
||||
_, err = localConn.WriteTo(broadcastPacket, broadcastAddress)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond * 500)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue