ipcam 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/ipcam/version.rb +1 -1
- data/lib/ipcam/webserver.rb +73 -41
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 364d7aea8083301b5c3bfd0ec5c26d8afa68ac6496433495da0e56812f4dafe0
|
4
|
+
data.tar.gz: '09776c05b93354b60adaf89314d3c4f0ba1878ef83bd4cef1410cc72ba0639bb'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 983cdf9103d28102f42f76f8b230b84c5ece86c41f94d01c78cce4a1d97461e7ff25c60eb344f508e107a338a3fedcd9eb880b11fe9712a121692580b33cb549
|
7
|
+
data.tar.gz: eb89a8b0d1ad4e512f764e292c9fb61b237571bfc4bf4d785db335020704d58fe025ea0257f090911cd21fde6007c26423d74a9fe77f787bb2032ab326df33c0
|
data/lib/ipcam/version.rb
CHANGED
data/lib/ipcam/webserver.rb
CHANGED
@@ -8,7 +8,6 @@
|
|
8
8
|
#
|
9
9
|
|
10
10
|
require 'sinatra/base'
|
11
|
-
require 'sinatra/streaming'
|
12
11
|
require 'puma'
|
13
12
|
require 'puma/configuration'
|
14
13
|
require 'puma/events'
|
@@ -65,58 +64,91 @@ module IPCam
|
|
65
64
|
erb :settings
|
66
65
|
end
|
67
66
|
|
67
|
+
head "/stream" do
|
68
|
+
halt 500 if app.abort?
|
69
|
+
halt 404 if app.stop?
|
70
|
+
halt 503 if not env["rack.hijack?"]
|
71
|
+
|
72
|
+
headers = {
|
73
|
+
"Content-Type" =>"multipart/x-mixed-replace;",
|
74
|
+
"Connection" => "close",
|
75
|
+
}
|
76
|
+
|
77
|
+
[200, headers, nil]
|
78
|
+
end
|
79
|
+
|
68
80
|
get "/stream" do
|
69
81
|
halt 500 if app.abort?
|
70
82
|
halt 404 if app.stop?
|
83
|
+
halt 503 if not env["rack.hijack?"]
|
71
84
|
|
72
85
|
boundary = SecureRandom.hex(20)
|
73
86
|
queue = Thread::Queue.new
|
87
|
+
headers = {
|
88
|
+
"Content-Type" =>"multipart/x-mixed-replace; boundary=#{boundary}",
|
89
|
+
"Connection" => "close",
|
74
90
|
|
75
|
-
|
91
|
+
# Rackのhijack API経由で生ソケットを用いてストリーミングを行う
|
92
|
+
"rack.hijack" => -> (sock) {
|
93
|
+
begin
|
94
|
+
app.add_client(queue)
|
95
|
+
|
96
|
+
sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_QUICKACK, 1)
|
97
|
+
sock.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
98
|
+
|
99
|
+
sock.write("\r\n".b)
|
100
|
+
sock.flush
|
101
|
+
|
102
|
+
fc = 0
|
103
|
+
|
104
|
+
loop {
|
105
|
+
body = queue.deq
|
106
|
+
break if not body
|
107
|
+
|
108
|
+
if $extend_header
|
109
|
+
header = <<~EOT.b
|
110
|
+
--#{boundary}
|
111
|
+
Content-Type: image/jpeg\r
|
112
|
+
Content-Length: #{body.bytesize}\r
|
113
|
+
X-Frame-Number: #{fc}
|
114
|
+
X-Timestamp: #{(Time.now.to_f * 1000).round}
|
115
|
+
\r
|
116
|
+
EOT
|
117
|
+
else
|
118
|
+
header = <<~EOT.b
|
119
|
+
--#{boundary}
|
120
|
+
Content-Type: image/jpeg\r
|
121
|
+
Content-Length: #{body.bytesize}\r
|
122
|
+
\r
|
123
|
+
EOT
|
124
|
+
end
|
125
|
+
|
126
|
+
sock.write(header, body)
|
127
|
+
sock.flush
|
128
|
+
fc += 1
|
129
|
+
|
130
|
+
# データ詰まりを防ぐ為にキューをクリア
|
131
|
+
queue.clear
|
132
|
+
}
|
133
|
+
|
134
|
+
rescue
|
135
|
+
# ignore
|
76
136
|
|
77
|
-
|
78
|
-
|
79
|
-
stream do |port|
|
80
|
-
port.callback {
|
81
|
-
app.remove_client(queue)
|
82
|
-
queue.clear
|
83
|
-
queue << nil
|
84
|
-
}
|
137
|
+
ensure
|
138
|
+
sock.close
|
85
139
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
fc = 0
|
90
|
-
|
91
|
-
loop {
|
92
|
-
data = queue.deq
|
93
|
-
break if not data
|
94
|
-
|
95
|
-
if $extend_header
|
96
|
-
port << <<~EOT.b
|
97
|
-
--#{boundary}
|
98
|
-
Content-Type: image/jpeg\r
|
99
|
-
Content-Length: #{data.bytesize}\r
|
100
|
-
X-Frame-Number: #{fc}
|
101
|
-
X-Timestamp: #{(Time.now.to_f * 1000).round}
|
102
|
-
\r
|
103
|
-
EOT
|
104
|
-
else
|
105
|
-
port << <<~EOT.b
|
106
|
-
--#{boundary}
|
107
|
-
Content-Type: image/jpeg\r
|
108
|
-
Content-Length: #{data.bytesize}\r
|
109
|
-
\r
|
110
|
-
EOT
|
140
|
+
app.remove_client(queue)
|
141
|
+
queue.clear
|
111
142
|
end
|
112
|
-
|
113
|
-
port << data
|
114
|
-
fc += 1
|
115
|
-
|
116
|
-
# データ詰まりを防ぐ為にキューをクリア
|
117
|
-
queue.clear
|
118
143
|
}
|
144
|
+
}
|
145
|
+
|
146
|
+
# ↓力業でsinatraがContent-Lengthを付与仕様とするのを抑止している
|
147
|
+
def response.calculate_content_length?
|
148
|
+
return false
|
119
149
|
end
|
150
|
+
|
151
|
+
[200, headers, nil]
|
120
152
|
end
|
121
153
|
|
122
154
|
get %r{/css/(.+).scss} do |name|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ipcam
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hirosho Kuwagata
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|