Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
autoradio
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ale
autoradio
Commits
77031ac6
Commit
77031ac6
authored
10 years ago
by
ale
Browse files
Options
Downloads
Patches
Plain Diff
more controls on encoding params; fix radioctl edit-mount
parent
d9e1bf1f
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
api.go
+34
-5
34 additions, 5 deletions
api.go
cmd/radioctl/radioctl.go
+179
-26
179 additions, 26 deletions
cmd/radioctl/radioctl.go
node/liquidsoap.go
+3
-1
3 additions, 1 deletion
node/liquidsoap.go
with
216 additions
and
32 deletions
api.go
+
34
−
5
View file @
77031ac6
...
...
@@ -50,22 +50,51 @@ type EncodingParams struct {
BitRate
int
SampleRate
int
Channels
int
StereoMode
string
Quality
float64
}
// NewEncodingParams sets some default values.
func
NewEncodingParams
()
*
EncodingParams
{
return
&
EncodingParams
{
SampleRate
:
44100
,
Channels
:
2
,
Quality
:
-
1
,
}
}
func
(
p
*
EncodingParams
)
Valid
()
error
{
if
p
.
Format
==
""
{
switch
p
.
Format
{
case
"mp3"
,
"mp3.cbr"
,
"mp3.abr"
,
"vorbis.cbr"
,
"vorbis.abr"
:
if
p
.
BitRate
==
0
{
return
errors
.
New
(
"bitrate not specified"
)
}
case
"mp3.vbr"
:
if
p
.
Quality
<
0
||
p
.
Quality
>
9
{
return
errors
.
New
(
"quality must be in range [0, 9]"
)
}
case
"vorbis"
:
if
p
.
Quality
<
-
0.2
||
p
.
Quality
>
1
{
return
errors
.
New
(
"quality must be in range [-0.2, 1]"
)
}
case
""
:
return
errors
.
New
(
"format not specified"
)
default
:
return
fmt
.
Errorf
(
"unknown format
\"
%s
\"
"
,
p
.
Format
)
}
if
p
.
SampleRate
==
0
{
return
errors
.
New
(
"sample rate not specified"
)
}
if
p
.
BitRate
==
0
&&
p
.
Quality
==
0
{
return
errors
.
New
(
"either bitrate or quality must be specified"
)
}
if
p
.
Channels
<
1
{
if
p
.
Channels
<
1
||
p
.
Channels
>
2
{
return
errors
.
New
(
"bad number of channels"
)
}
if
p
.
Channels
>
1
{
switch
p
.
StereoMode
{
case
""
,
"stereo"
,
"joint_stereo"
,
"default"
:
default
:
return
fmt
.
Errorf
(
"unknown stereo mode
\"
%s
\"
"
,
p
.
StereoMode
)
}
}
return
nil
}
...
...
This diff is collapsed.
Click to expand it.
cmd/radioctl/radioctl.go
+
179
−
26
View file @
77031ac6
...
...
@@ -8,6 +8,7 @@ import (
"log"
"net/url"
"os"
"strconv"
"strings"
"git.autistici.org/ale/autoradio"
...
...
@@ -18,6 +19,97 @@ import (
// Format for output of structured data.
var
outputFormat
=
flag
.
String
(
"format"
,
"txt"
,
"Output format for structured data (json, txt)"
)
type
optionalValue
struct
{
isSet
bool
}
func
(
v
*
optionalValue
)
IsSet
()
bool
{
return
v
.
isSet
}
type
stringOptionalValue
struct
{
*
optionalValue
value
string
}
func
newStringOptionalValue
()
*
stringOptionalValue
{
return
&
stringOptionalValue
{}
}
func
(
v
*
stringOptionalValue
)
Set
(
val
string
)
error
{
v
.
isSet
=
true
v
.
value
=
val
return
nil
}
func
(
v
*
stringOptionalValue
)
Value
()
string
{
return
v
.
value
}
func
(
v
*
stringOptionalValue
)
String
()
string
{
return
v
.
value
}
func
(
v
*
stringOptionalValue
)
Get
()
interface
{}
{
return
v
.
value
}
type
intOptionalValue
struct
{
*
optionalValue
value
int
}
func
newIntOptionalValue
()
*
intOptionalValue
{
return
&
intOptionalValue
{}
}
func
(
v
*
intOptionalValue
)
Set
(
val
string
)
error
{
ival
,
err
:=
strconv
.
Atoi
(
val
)
v
.
value
=
ival
v
.
isSet
=
true
return
err
}
func
(
v
*
intOptionalValue
)
Value
()
int
{
return
v
.
value
}
func
(
v
*
intOptionalValue
)
String
()
string
{
return
fmt
.
Sprintf
(
"%v"
,
v
.
value
)
}
func
(
v
*
intOptionalValue
)
Get
()
interface
{}
{
return
v
.
value
}
type
floatOptionalValue
struct
{
*
optionalValue
value
float64
}
func
newFloatOptionalValue
()
*
floatOptionalValue
{
return
&
floatOptionalValue
{}
}
func
(
v
*
floatOptionalValue
)
Set
(
val
string
)
error
{
fval
,
err
:=
strconv
.
ParseFloat
(
val
,
64
)
v
.
value
=
fval
v
.
isSet
=
true
return
err
}
func
(
v
*
floatOptionalValue
)
Value
()
float64
{
return
v
.
value
}
func
(
v
*
floatOptionalValue
)
String
()
string
{
return
fmt
.
Sprintf
(
"%v"
,
v
.
value
)
}
func
(
v
*
floatOptionalValue
)
Get
()
interface
{}
{
return
v
.
value
}
type
HasAddFlags
interface
{
AddFlags
(
*
gonutsflag
.
FlagSet
)
}
...
...
@@ -99,15 +191,6 @@ func printMount(m *autoradio.Mount) {
}
}
func
addEncodingFlags
(
f
*
gonutsflag
.
FlagSet
,
p
*
autoradio
.
EncodingParams
)
{
f
.
StringVar
(
&
p
.
SourceName
,
"source"
,
""
,
"Source mountpoint"
)
f
.
StringVar
(
&
p
.
Format
,
"codec"
,
""
,
"Encoding format"
)
f
.
IntVar
(
&
p
.
BitRate
,
"bitrate"
,
0
,
"Bitrate (kbps)"
)
f
.
IntVar
(
&
p
.
SampleRate
,
"samplerate"
,
0
,
"Sample rate (Hz)"
)
f
.
IntVar
(
&
p
.
Channels
,
"channels"
,
2
,
"Number of channels"
)
f
.
Float64Var
(
&
p
.
Quality
,
"quality"
,
0
,
"Quality (alternatively to bitrate for some encoders)"
)
}
func
mountExists
(
name
string
,
client
*
autoradio
.
Client
)
bool
{
m
,
_
:=
client
.
GetMount
(
name
)
return
m
!=
nil
...
...
@@ -184,16 +267,26 @@ func newCreateTranscodingMountCommand() *createTranscodingMountCommand {
return
&
createTranscodingMountCommand
{
BaseCommand
:
BaseCommand
{
UsageLine
:
"create-transcoding-mount <path>"
,
Short
:
"Create a transcod
ed
mount"
,
Short
:
"Create a transcod
ing
mount"
,
Long
:
`
Create a new stream that will transcode the parent stream with
different encoding parameters.
`
,
},
params
:
&
autoradio
.
EncodingParams
{}
,
params
:
autoradio
.
New
EncodingParams
()
,
}
}
func
addEncodingFlags
(
f
*
gonutsflag
.
FlagSet
,
p
*
autoradio
.
EncodingParams
)
{
f
.
StringVar
(
&
p
.
SourceName
,
"source"
,
""
,
"Source mountpoint"
)
f
.
StringVar
(
&
p
.
Format
,
"codec"
,
p
.
Format
,
"Encoding format"
)
f
.
Float64Var
(
&
p
.
Quality
,
"quality"
,
p
.
Quality
,
"Quality (for VBR encoders)"
)
f
.
IntVar
(
&
p
.
BitRate
,
"bitrate"
,
p
.
BitRate
,
"Bitrate (kbps)"
)
f
.
IntVar
(
&
p
.
SampleRate
,
"samplerate"
,
p
.
SampleRate
,
"Sample rate (Hz)"
)
f
.
IntVar
(
&
p
.
Channels
,
"channels"
,
p
.
Channels
,
"Number of channels"
)
f
.
StringVar
(
&
p
.
StereoMode
,
"stereo-mode"
,
p
.
StereoMode
,
"Stereo mode for mp3 codec (stereo, joint_stereo)"
)
}
func
(
cmd
*
createTranscodingMountCommand
)
AddFlags
(
f
*
gonutsflag
.
FlagSet
)
{
addEncodingFlags
(
f
,
cmd
.
params
)
f
.
StringVar
(
&
cmd
.
fallback
,
"fallback"
,
""
,
"Fallback stream URL"
)
...
...
@@ -242,9 +335,15 @@ func (cmd *createTranscodingMountCommand) Run(args []string) {
// Edit a mountpoint.
type
editMountCommand
struct
{
BaseCommand
params
*
autoradio
.
EncodingParams
relay
string
fallback
string
relay
*
stringOptionalValue
fallback
*
stringOptionalValue
transFormat
*
stringOptionalValue
transSource
*
stringOptionalValue
transBitRate
*
intOptionalValue
transSampleRate
*
intOptionalValue
transChannels
*
intOptionalValue
transStereoMode
*
stringOptionalValue
transQuality
*
floatOptionalValue
}
var
UNSET
=
"UNSET"
...
...
@@ -262,18 +361,45 @@ default, non-relay behavior, set the relay to the empty string
(with --relay="").
`
,
},
params
:
&
autoradio
.
EncodingParams
{},
relay
:
newStringOptionalValue
(),
fallback
:
newStringOptionalValue
(),
transFormat
:
newStringOptionalValue
(),
transSource
:
newStringOptionalValue
(),
transBitRate
:
newIntOptionalValue
(),
transSampleRate
:
newIntOptionalValue
(),
transChannels
:
newIntOptionalValue
(),
transStereoMode
:
newStringOptionalValue
(),
transQuality
:
newFloatOptionalValue
(),
}
}
func
(
cmd
*
editMountCommand
)
AddFlags
(
f
*
gonutsflag
.
FlagSet
)
{
// Note that we use a magic value to figure out whether a flag
// has been specified or not, to make it possible to clear a
// field (by setting it to the empty string). There might be
// better way to do this.
f
.
StringVar
(
&
cmd
.
relay
,
"relay"
,
UNSET
,
"Upstream URL to relay"
)
f
.
StringVar
(
&
cmd
.
fallback
,
"fallback"
,
UNSET
,
"Fallback stream URL"
)
addEncodingFlags
(
f
,
cmd
.
params
)
f
.
Var
(
cmd
.
relay
,
"relay"
,
"Upstream URL to relay"
)
f
.
Var
(
cmd
.
fallback
,
"fallback"
,
"Fallback stream URL"
)
f
.
Var
(
cmd
.
transSource
,
"source"
,
"[transcoding] Source mountpoint"
)
f
.
Var
(
cmd
.
transFormat
,
"codec"
,
"[transcoding] Encoding format"
)
f
.
Var
(
cmd
.
transQuality
,
"quality"
,
"[transcoding] Quality (for VBR encoders)"
)
f
.
Var
(
cmd
.
transBitRate
,
"bitrate"
,
"[transcoding] Bitrate (kbps)"
)
f
.
Var
(
cmd
.
transSampleRate
,
"samplerate"
,
"[transcoding] Sample rate (Hz)"
)
f
.
Var
(
cmd
.
transChannels
,
"channels"
,
"[transcoding] Number of channels"
)
f
.
Var
(
cmd
.
transStereoMode
,
"stereo-mode"
,
"[transcoding] Stereo mode for mp3 encoding (stereo, joint_stereo)"
)
}
func
(
cmd
*
editMountCommand
)
transcodingOptionsSet
()
bool
{
opts
:=
[]
interface
{
IsSet
()
bool
}{
cmd
.
transSource
,
cmd
.
transFormat
,
cmd
.
transQuality
,
cmd
.
transBitRate
,
cmd
.
transSampleRate
,
cmd
.
transChannels
,
cmd
.
transStereoMode
,
}
for
_
,
o
:=
range
opts
{
if
o
.
IsSet
()
{
return
true
}
}
return
false
}
func
(
cmd
*
editMountCommand
)
Run
(
args
[]
string
)
{
...
...
@@ -290,11 +416,38 @@ func (cmd *editMountCommand) Run(args []string) {
log
.
Fatal
(
"ERROR: mount not found"
)
}
if
cmd
.
fallback
!=
UNSET
{
m
.
Fallback
=
cmd
.
fallback
// Only set those fields that were passed on the command line.
if
cmd
.
fallback
.
IsSet
()
{
m
.
Fallback
=
cmd
.
fallback
.
Value
()
}
if
cmd
.
relay
.
IsSet
()
{
setRelay
(
m
,
cmd
.
relay
.
Value
())
}
if
cmd
.
transcodingOptionsSet
()
&&
m
.
Transcoding
==
nil
{
log
.
Fatal
(
"ERROR: can't set transcoding options on a non-transcoding mount (delete and re-create)"
)
}
if
cmd
.
transFormat
.
IsSet
()
{
m
.
Transcoding
.
Format
=
cmd
.
transFormat
.
Value
()
}
if
cmd
.
transSource
.
IsSet
()
{
m
.
Transcoding
.
SourceName
=
cmd
.
transSource
.
Value
()
}
if
cmd
.
transBitRate
.
IsSet
()
{
m
.
Transcoding
.
BitRate
=
cmd
.
transBitRate
.
Value
()
}
if
cmd
.
transSampleRate
.
IsSet
()
{
m
.
Transcoding
.
SampleRate
=
cmd
.
transSampleRate
.
Value
()
}
if
cmd
.
transQuality
.
IsSet
()
{
m
.
Transcoding
.
Quality
=
cmd
.
transQuality
.
Value
()
}
if
cmd
.
transChannels
.
IsSet
()
{
m
.
Transcoding
.
Channels
=
cmd
.
transChannels
.
Value
()
}
if
cmd
.
relay
!=
UNSET
{
setRelay
(
m
,
cmd
.
relay
)
if
cmd
.
transStereoMode
.
IsSet
()
{
m
.
Transcoding
.
StereoMode
=
cmd
.
transStereoMode
.
Value
(
)
}
if
err
:=
m
.
Valid
();
err
!=
nil
{
...
...
This diff is collapsed.
Click to expand it.
node/liquidsoap.go
+
3
−
1
View file @
77031ac6
...
...
@@ -24,7 +24,7 @@ set("log.file", false)
set("log.stdout", true)
upstream = mksafe(input.http("{{.SourceURL}}", buffer=5.0))
output.icecast(%{{.Format}}(samplerate={{.SampleRate}}, {{if gt .BitRate 0}}bitrate={{.BitRate}}, {{end}}{{if gt .Quality
0
.0}}quality={{.Quality}}, {{end}}{{if eq .Channels 2}}stereo{{else}}mono{{end}}),
output.icecast(%{{.Format}}(samplerate={{.SampleRate}}, {{if gt .BitRate 0}}bitrate={{.BitRate}}, {{end}}{{if gt .Quality
-1
.0}}quality={{.Quality}}, {{end}}{{if
.StereoMode}}stereo_mode={{.StereoMode}}, {{end}}{{if
eq .Channels 2}}stereo{{else}}mono{{end}}),
mount="{{.TargetMount}}", host="{{.TargetIP}}", port={{.TargetPort}}, user="{{.TargetUsername}}", password="{{.TargetPassword}}",
upstream)
`
...
...
@@ -51,6 +51,7 @@ type liquidsoapParams struct {
BitRate
int
SampleRate
int
Channels
int
StereoMode
string
Quality
float32
}
...
...
@@ -69,6 +70,7 @@ func newLiquidsoapParams(mount *autoradio.Mount) *liquidsoapParams {
BitRate
:
mount
.
Transcoding
.
BitRate
,
SampleRate
:
mount
.
Transcoding
.
SampleRate
,
Channels
:
mount
.
Transcoding
.
Channels
,
StereoMode
:
mount
.
Transcoding
.
StereoMode
,
Quality
:
float32
(
mount
.
Transcoding
.
Quality
),
}
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment