ffi-hdhomerun 0.2.aa238f1f25e6 → 0.3.100b91730e74
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.
- data/README.txt +30 -38
- data/lib/ffi-hdhomerun.rb +98 -41
- data/lib/ffi/hdhomerun.rb +9 -1
- metadata +5 -5
data/README.txt
CHANGED
@@ -1,22 +1,17 @@
|
|
1
|
-
ffi-hdhomerun
|
2
|
-
==========
|
1
|
+
= ffi-hdhomerun
|
3
2
|
http://bitbucket.org/dmlary/ffi-hdhomerun
|
4
3
|
|
5
|
-
Description
|
6
|
-
-----------
|
4
|
+
== Description
|
7
5
|
Ruby-FFI bindings and wrappers for libhdhomerun.
|
8
6
|
|
9
|
-
Features
|
10
|
-
--------
|
7
|
+
== Features
|
11
8
|
Allows the user to capture video from an HDHomeRun device within Ruby.
|
12
9
|
|
13
|
-
What's missing
|
14
|
-
--------------
|
10
|
+
== What's missing
|
15
11
|
* Discovery
|
16
12
|
* Documentation
|
17
13
|
|
18
|
-
Usage
|
19
|
-
-----
|
14
|
+
== Usage
|
20
15
|
require 'ffi-hdhomerun'
|
21
16
|
|
22
17
|
# Allocate a tuner
|
@@ -36,35 +31,32 @@ Usage
|
|
36
31
|
end
|
37
32
|
end
|
38
33
|
|
39
|
-
Requirements
|
40
|
-
|
41
|
-
|
42
|
-
* ffi >= 1.0
|
34
|
+
== Requirements
|
35
|
+
- libhdhomerun >= 1.0
|
36
|
+
- ffi >= 1.0
|
43
37
|
|
44
|
-
Copyright
|
45
|
-
---------
|
38
|
+
== Copyright
|
46
39
|
Copyright (c) 2011, David M. Lary
|
47
40
|
All rights reserved.
|
48
41
|
|
49
|
-
License
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
42
|
+
== License
|
43
|
+
Redistribution and use in source and binary forms, with or without
|
44
|
+
modification, are permitted provided that the following conditions are met:
|
45
|
+
* Redistributions of source code must retain the above copyright
|
46
|
+
notice, this list of conditions and the following disclaimer.
|
47
|
+
* Redistributions in binary form must reproduce the above copyright
|
48
|
+
notice, this list of conditions and the following disclaimer in the
|
49
|
+
documentation and/or other materials provided with the distribution.
|
50
|
+
* The name of the author may not be used to endorse or promote products
|
51
|
+
derived from this software without specific prior written permission.
|
52
|
+
|
53
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
54
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
55
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
56
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
57
|
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
58
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
59
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
60
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
61
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
62
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/lib/ffi-hdhomerun.rb
CHANGED
@@ -1,8 +1,38 @@
|
|
1
1
|
require 'ffi/hdhomerun'
|
2
2
|
|
3
|
+
#
|
4
|
+
# Documentation can be found under HDHomeRun::Tuner
|
5
|
+
#
|
3
6
|
module HDHomeRun
|
4
|
-
VERSION = "0.
|
5
|
-
|
7
|
+
VERSION = "0.3"
|
8
|
+
|
9
|
+
# HDHomeRun tuner wrapper.
|
10
|
+
#
|
11
|
+
# Basic usage:
|
12
|
+
#
|
13
|
+
# # Get a tuner instance for the first tuner on the network.
|
14
|
+
# tuner = HDHomeRun::Tuner.new(:id => "FFFFFFFF", :tuner => 0)
|
15
|
+
#
|
16
|
+
# # Set the channel and program
|
17
|
+
# tuner.channel = 20
|
18
|
+
# tuner.program = 3
|
19
|
+
#
|
20
|
+
# # Open a file to write the video stream to
|
21
|
+
# File.open("capture.ts", "w") do |output|
|
22
|
+
# puts "Capturing (^C to stop):"
|
23
|
+
#
|
24
|
+
# # Read the video stream from the tuner
|
25
|
+
# tuner.capture do |video_data|
|
26
|
+
#
|
27
|
+
# # write the video data to the output file
|
28
|
+
# output.write(video_data)
|
29
|
+
#
|
30
|
+
# # Display some sort of feedback to show we're capturing.
|
31
|
+
# STDOUT.write(video_data.size > 0 ? "." : "?")
|
32
|
+
# STDOUT.flush
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
#
|
6
36
|
class Tuner
|
7
37
|
include FFI::HDHomeRun
|
8
38
|
|
@@ -11,13 +41,22 @@ module HDHomeRun
|
|
11
41
|
# Initialize new hdhomerun tuner
|
12
42
|
#
|
13
43
|
# Arguments:
|
14
|
-
#
|
15
|
-
#
|
44
|
+
# [:id] HDHomeRun id (default: "FFFFFFFF")
|
45
|
+
# [:tuner] Tuner number (default: "/tuner0")
|
46
|
+
#
|
47
|
+
# Create a tuner instance for the first tuner on any HDHomeRun box
|
48
|
+
# on the network:
|
49
|
+
# tuner => HDHomeRun::Tuner.new(0)
|
50
|
+
#
|
51
|
+
# Create a tuner instance for the second tuner on the HDHomeRun box
|
52
|
+
# with id FE92EBD0
|
53
|
+
# tuner = HDHomeRun::Tuner.new(:id => "FE92EBD0", :tuner => 1)
|
16
54
|
#
|
17
55
|
def initialize(p={})
|
18
56
|
p = {:id => p} unless p.is_a? Hash
|
19
57
|
p[:id] ||= "FFFFFFFF"
|
20
|
-
p[:tuner] ||=
|
58
|
+
p[:tuner] ||= 0
|
59
|
+
p[:tuner] = "/tuner%d" % p[:tuner] if p[:tuner].is_a? Fixnum
|
21
60
|
|
22
61
|
@hd = create_from_str(p[:id].to_s, nil)
|
23
62
|
raise ArgumentError, "Invalid device id: #{id}" if @hd.null?
|
@@ -35,42 +74,6 @@ module HDHomeRun
|
|
35
74
|
unless get_model_str(@hd)
|
36
75
|
end
|
37
76
|
|
38
|
-
def get(key)
|
39
|
-
value = FFI::MemoryPointer.new(:pointer, 1)
|
40
|
-
error = FFI::MemoryPointer.new(:pointer, 1)
|
41
|
-
|
42
|
-
if get_var(@hd, key, value, error) < 0
|
43
|
-
raise RuntimeError,
|
44
|
-
"communication error sending request to hdhomerun device"
|
45
|
-
end
|
46
|
-
value = value.read_pointer
|
47
|
-
error = error.read_pointer
|
48
|
-
|
49
|
-
raise RuntimeError, error.read_string unless error.null?
|
50
|
-
value.read_string
|
51
|
-
end
|
52
|
-
|
53
|
-
def set(key, value)
|
54
|
-
error = FFI::MemoryPointer.new(:pointer, 1)
|
55
|
-
|
56
|
-
if set_var(@hd, key, value.to_s, nil, error) < 0
|
57
|
-
raise RuntimeError,
|
58
|
-
"communication error sending request to hdhomerun device"
|
59
|
-
end
|
60
|
-
error = error.read_pointer
|
61
|
-
|
62
|
-
raise RuntimeError, error.read_string unless error.null?
|
63
|
-
true
|
64
|
-
end
|
65
|
-
|
66
|
-
def get_tuner(key)
|
67
|
-
get("%s/%s" % [@tuner, key.to_s])
|
68
|
-
end
|
69
|
-
|
70
|
-
def set_tuner(key, value)
|
71
|
-
set("%s/%s" % [@tuner, key.to_s], value)
|
72
|
-
end
|
73
|
-
|
74
77
|
# Dynamically define the following getter and setter methods
|
75
78
|
%w{channel channelmap filter program target}.each do |name|
|
76
79
|
define_method name do
|
@@ -89,6 +92,9 @@ module HDHomeRun
|
|
89
92
|
end
|
90
93
|
end
|
91
94
|
|
95
|
+
# Get the capture statistics for the tuner.
|
96
|
+
#
|
97
|
+
# Returns: FFI::HDHomeRun::Stats
|
92
98
|
def stats
|
93
99
|
ptr = FFI::MemoryPointer.new Stats
|
94
100
|
out = Stats.new ptr;
|
@@ -96,6 +102,19 @@ module HDHomeRun
|
|
96
102
|
out
|
97
103
|
end
|
98
104
|
|
105
|
+
# Capture video data from the tuner.
|
106
|
+
#
|
107
|
+
# As data is received from the tuner, that data will be yielded to the
|
108
|
+
# block provided. If no data has been received from the tuner in over
|
109
|
+
# a second, capture will yield a string of length zero to the block.
|
110
|
+
#
|
111
|
+
# If the block returns [false], the tuner will stop capturing and return.
|
112
|
+
#
|
113
|
+
# Capture from the tuner, but abort if we see no data:
|
114
|
+
# tuner.capture do |buf|
|
115
|
+
# break false if buf.empty?
|
116
|
+
# end
|
117
|
+
#
|
99
118
|
def capture(p={}, &block)
|
100
119
|
raise ArgumentError, "no block" unless block_given?
|
101
120
|
raise RuntimeError, "unable to start stream" \
|
@@ -127,5 +146,43 @@ module HDHomeRun
|
|
127
146
|
stream_stop(@hd)
|
128
147
|
end
|
129
148
|
end
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
def get(key)
|
153
|
+
value = FFI::MemoryPointer.new(:pointer, 1)
|
154
|
+
error = FFI::MemoryPointer.new(:pointer, 1)
|
155
|
+
|
156
|
+
if get_var(@hd, key, value, error) < 0
|
157
|
+
raise RuntimeError,
|
158
|
+
"communication error sending request to hdhomerun device"
|
159
|
+
end
|
160
|
+
value = value.read_pointer
|
161
|
+
error = error.read_pointer
|
162
|
+
|
163
|
+
raise RuntimeError, error.read_string unless error.null?
|
164
|
+
value.read_string
|
165
|
+
end
|
166
|
+
|
167
|
+
def set(key, value)
|
168
|
+
error = FFI::MemoryPointer.new(:pointer, 1)
|
169
|
+
|
170
|
+
if set_var(@hd, key, value.to_s, nil, error) < 0
|
171
|
+
raise RuntimeError,
|
172
|
+
"communication error sending request to hdhomerun device"
|
173
|
+
end
|
174
|
+
error = error.read_pointer
|
175
|
+
|
176
|
+
raise RuntimeError, error.read_string unless error.null?
|
177
|
+
true
|
178
|
+
end
|
179
|
+
|
180
|
+
def get_tuner(key)
|
181
|
+
get("%s/%s" % [@tuner, key.to_s])
|
182
|
+
end
|
183
|
+
|
184
|
+
def set_tuner(key, value)
|
185
|
+
set("%s/%s" % [@tuner, key.to_s], value)
|
186
|
+
end
|
130
187
|
end
|
131
188
|
end
|
data/lib/ffi/hdhomerun.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'ffi'
|
2
2
|
|
3
|
-
module FFI
|
3
|
+
module FFI # :nodoc:
|
4
4
|
module HDHomeRun
|
5
5
|
extend FFI::Library
|
6
6
|
ffi_lib "libhdhomerun.so.1"
|
@@ -41,6 +41,14 @@ module FFI
|
|
41
41
|
:hdhomerun_device_get_video_stats,
|
42
42
|
[:pointer, :pointer], :void
|
43
43
|
|
44
|
+
# HDHomeRun capture statistics for a given tuner
|
45
|
+
#
|
46
|
+
# packets:: Number of packets captured
|
47
|
+
# network_errors:: Number of network errors
|
48
|
+
# transport_errors:: Number of transport errors
|
49
|
+
# sequence_errors:: Number of sequence errors
|
50
|
+
# overflow_errors:: Number of overflow errors
|
51
|
+
#
|
44
52
|
class Stats < FFI::Struct
|
45
53
|
layout :packets, :uint,
|
46
54
|
:network_errors, :uint,
|
metadata
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffi-hdhomerun
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.3.100b91730e74
|
5
|
+
prerelease: 7
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- David M. Lary
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-10-03 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
16
|
-
requirement: &
|
16
|
+
requirement: &12302400 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *12302400
|
25
25
|
description: Ruby FFI bindings for libhdhomerun
|
26
26
|
email:
|
27
27
|
- dmlary@gmail.com
|