Skip to content

Commit b9f277f

Browse files
authored
Merge pull request #10 from amattu2/battery-device-liveview-fix
fix: Premature livestream timeout for low power devices
2 parents ef0fe28 + 9ae0dde commit b9f277f

File tree

5 files changed

+39
-27
lines changed

5 files changed

+39
-27
lines changed

account/account.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,17 @@ getDevice:
8181
cancelCtx()
8282
}()
8383

84-
common.Livestream(ctx, common.AccountDetails{
84+
accountDetails := common.AccountDetails{
8585
Region: region,
8686
Token: token,
8787
DeviceType: device.DeviceType,
8888
AccountId: accountId,
8989
NetworkId: device.NetworkId,
9090
CameraId: device.DeviceId,
91-
}, inputPipe)
91+
}
92+
if err := common.Livestream(ctx, accountDetails, inputPipe); err != nil {
93+
log.Println("error starting liveview session", err)
94+
}
9295

9396
inputPipe.Close()
9497
if err := ffplayCmd.Wait(); err != nil {

common/livestream.go

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"fmt"
66
"io"
7-
"log"
87
)
98

109
type AccountDetails struct {
@@ -40,18 +39,15 @@ func Livestream(ctx context.Context, account AccountDetails, writer io.Writer) e
4039
baseUrl := GetApiUrl(account.Region)
4140
liveViewPath, err := GetLiveviewPath(account.DeviceType)
4241
if err != nil {
43-
log.Println("Error getting liveview path", err)
44-
return err
42+
return fmt.Errorf("error getting liveview path: %w", err)
4543
}
4644

4745
// Tell Blink we want to start a liveview session
4846
resp, err := BeginLiveview(fmt.Sprintf(liveViewPath, baseUrl, account.AccountId, account.NetworkId, account.CameraId), account.Token)
4947
if err != nil {
50-
log.Println("Error starting liveview session", err)
51-
return err
48+
return fmt.Errorf("error starting liveview session: %w", err)
5249
} else if resp == nil || resp.CommandId == 0 {
53-
log.Println("Error sending liveview command", resp)
54-
return fmt.Errorf("error sending liveview command")
50+
return fmt.Errorf("error sending liveview command: %v", resp)
5551
}
5652

5753
// Poll the liveview command to keep the connection alive
@@ -61,14 +57,12 @@ func Livestream(ctx context.Context, account AccountDetails, writer io.Writer) e
6157
// Get the connection details
6258
connectionDetails, err := ParseConnectionString(resp.Server)
6359
if err != nil {
64-
log.Println("Error parsing connection string", err)
65-
return err
60+
return fmt.Errorf("connection string parsing error: %w", err)
6661
}
6762

6863
// Connect to the liveview server
6964
if err := TCPStream(ctx, *connectionDetails, writer); err != nil {
70-
log.Println("TCPStream error:", err)
71-
return err
65+
return fmt.Errorf("TCPStream error: %w", err)
7266
}
7367

7468
<-ctx.Done()

common/tcp.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,16 @@ import (
1212
"time"
1313
)
1414

15+
// READ_TIMEOUT is the timeout for reading from the TCP connection.
16+
// Low power devices may take longer than usual before receiving initial data.
17+
var READ_TIMEOUT = 10 * time.Second
18+
19+
// FRAMES_KEEPALIVE is the keep-alive ping frame sent to the Blink stream server.
1520
var FRAMES_KEEPALIVE = []byte{
16-
0x12, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
17-
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
21+
0x12, 0x00, 0x00, 0x03, 0xe8, 0x00, 0x00, 0x00,
22+
0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
1825
0x00,
1926
}
2027

@@ -74,7 +81,7 @@ stream:
7481
log.Println("Closing stream")
7582
break stream
7683
default:
77-
if err := client.SetReadDeadline(time.Now().Add(2 * time.Second)); err != nil {
84+
if err := client.SetReadDeadline(time.Now().Add(READ_TIMEOUT)); err != nil {
7885
streamErr = fmt.Errorf("error setting read deadline: %w", err)
7986
break stream
8087
}

handlers/websocket.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -73,15 +73,20 @@ func liveviewHandler(ctx context.Context, c *websocket.Conn, data map[string]int
7373
}
7474
defer ffmpegCmd.Process.Kill()
7575

76-
// TODO: Handle Livestream errors and propagate them to the client
77-
go common.Livestream(ctx, common.AccountDetails{
78-
Region: region,
79-
Token: token,
80-
DeviceType: device_type,
81-
AccountId: account_id,
82-
NetworkId: network_id,
83-
CameraId: camera_id,
84-
}, inputPipe)
76+
go func() {
77+
err := common.Livestream(ctx, common.AccountDetails{
78+
Region: region,
79+
Token: token,
80+
DeviceType: device_type,
81+
AccountId: account_id,
82+
NetworkId: network_id,
83+
CameraId: camera_id,
84+
}, inputPipe)
85+
if err != nil {
86+
log.Println("error starting liveview session", err)
87+
// TODO: Notify the client about the error
88+
}
89+
}()
8590

8691
// Tell the client that the liveview has started
8792
c.WriteJSON(CommandMessage{

liveview/liveview.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,17 @@ func Run(region string, token string, deviceType string, accountId int, networkI
3535
cancelCtx()
3636
}()
3737

38-
common.Livestream(ctx, common.AccountDetails{
38+
accountDetails := common.AccountDetails{
3939
Region: region,
4040
Token: token,
4141
DeviceType: deviceType,
4242
AccountId: accountId,
4343
NetworkId: networkId,
4444
CameraId: cameraId,
45-
}, inputPipe)
45+
}
46+
if err := common.Livestream(ctx, accountDetails, inputPipe); err != nil {
47+
log.Println("error during livestream", err)
48+
}
4649

4750
inputPipe.Close()
4851
if err := ffplayCmd.Wait(); err != nil {

0 commit comments

Comments
 (0)