Skip to content

Commit

Permalink
Add odysee extractor (#1379)
Browse files Browse the repository at this point in the history
* Add Odysee

* Add Odysee link
  • Loading branch information
shavit committed Aug 14, 2024
1 parent 5eebf7f commit c5135e9
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 0 deletions.
31 changes: 31 additions & 0 deletions .github/workflows/stream_odysee.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: odysee

on:
push:
paths:
- "extractors/odysee/*.go"
- ".github/workflows/stream_odysee.yml"
pull_request:
paths:
- "extractors/odysee/*.go"
- ".github/workflows/stream_odysee.yml"
schedule:
# run ci weekly
- cron: "0 0 * * 0"

jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
go: ["1.22"]
os: [ubuntu-latest]
name: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go }}

- name: Test
run: go test -timeout 5m -race -coverpkg=./... -coverprofile=coverage.txt github.com/iawia002/lux/extractors/odysee
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ $ lux -j "https://www.bilibili.com/video/av20203945"
| 小红书 | <https://xiaohongshu.com> || | | | | [![xiaohongshu](https://github.com/iawia002/lux/actions/workflows/stream_xiaohongshu.yml/badge.svg)](https://github.com/iawia002/lux/actions/workflows/stream_xiaohongshu.yml/) |
| Zing MP3 | <https://zingmp3.vn> || || | | [![zingmp3](https://github.com/iawia002/lux/actions/workflows/stream_zingmp3.yml/badge.svg)](https://github.com/iawia002/lux/actions/workflows/stream_zingmp3.yml/) |
| Bitchute | <https://www.bitchute.com> || | | | | [![bitchute](https://github.com/iawia002/lux/actions/workflows/stream_bitchute.yml/badge.svg)](https://github.com/iawia002/lux/actions/workflows/stream_bitchute.yml/) |
| Odysee | <https://odysee.com> || || | | [![odysee](https://github.com/iawia002/lux/actions/workflows/stream_odysee.yml/badge.svg)](https://github.com/iawia002/lux/actions/workflows/stream_odysee.yml/) |


## Known issues
Expand Down
1 change: 1 addition & 0 deletions app/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
_ "github.com/iawia002/lux/extractors/mgtv"
_ "github.com/iawia002/lux/extractors/miaopai"
_ "github.com/iawia002/lux/extractors/netease"
_ "github.com/iawia002/lux/extractors/odysee"
_ "github.com/iawia002/lux/extractors/pinterest"
_ "github.com/iawia002/lux/extractors/pixivision"
_ "github.com/iawia002/lux/extractors/pornhub"
Expand Down
96 changes: 96 additions & 0 deletions extractors/odysee/odysee.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package odysee

import (
"compress/flate"
"compress/gzip"
"encoding/json"
"io"
"net/http"
"regexp"

"github.com/iawia002/lux/extractors"
"github.com/iawia002/lux/request"
"github.com/pkg/errors"
)

func init() {
extractors.Register("odysee", New())
}

type extractor struct{}

type odyseePayload struct {
ContentURL string `json:"contentUrl"`
Description string `json:"description"`
Name string `json:"name"`
ThumbnailURL string `json:"thumbnailUrl"`
URL string `json:"url"`
}

// New returns an odysee extractor.
func New() extractors.Extractor {
return &extractor{}
}

func (e *extractor) Extract(u string, option extractors.Options) ([]*extractors.Data, error) {
res, err := request.Request(http.MethodGet, u, nil, nil)
if err != nil {
return nil, errors.WithStack(err)
}
defer res.Body.Close() // nolint

var reader io.ReadCloser
switch res.Header.Get("Content-Encoding") {
case "gzip":
reader, _ = gzip.NewReader(res.Body)
case "deflate":
reader = flate.NewReader(res.Body)
default:
reader = res.Body
}
defer reader.Close() // nolint

b, err := io.ReadAll(reader)
if err != nil {
return nil, errors.WithStack(err)
}

regScript := regexp.MustCompile(`(?im)\<script type="application\/ld\+json"\>([\s\S]*)[\n?]<\/script>`)
matchPayload := regScript.FindSubmatch(b)
if len(matchPayload) < 2 {
return nil, errors.New("Could not read page data")
}

var resData odyseePayload
if err := json.Unmarshal(matchPayload[1], &resData); err != nil {
return nil, errors.WithStack(err)
}

streams := make(map[string]*extractors.Stream, 1)
size, err := request.Size(resData.ContentURL, u)
if err != nil {
return nil, errors.WithStack(err)
}

streams["Default"] = &extractors.Stream{
Parts: []*extractors.Part{
{
URL: resData.ContentURL,
Size: size,
Ext: "mp4",
},
},
Size: size,
Quality: "Default",
}

return []*extractors.Data{
{
Site: "Odysee odysee.com",
Title: resData.Name,
Type: extractors.DataTypeVideo,
Streams: streams,
URL: u,
},
}, nil
}
39 changes: 39 additions & 0 deletions extractors/odysee/odysee_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package odysee

import (
"testing"

"github.com/iawia002/lux/extractors"
"github.com/iawia002/lux/test"
)

func TestDownload(t *testing.T) {
tests := []struct {
name string
args test.Args
}{
{
name: "video test 1",
args: test.Args{
URL: "https://odysee.com/@FunnyPets:4e/funny-pets-378-funny-shorts:6",
Title: "Funny Pets 378 #funny #shorts",
Size: 1144972,
},
},
{
name: "video test 2",
args: test.Args{
URL: "https://odysee.com/@FunnyPets:4e/best-of-funny-pets-week-2-funny-pets:a",
Title: "Best of Funny Pets Week 2 #funny #pets",
Size: 167272140,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
data, err := New().Extract(tt.args.URL, extractors.Options{})
test.CheckError(t, err)
test.Check(t, tt.args, data[0])
})
}
}

0 comments on commit c5135e9

Please sign in to comment.