File size: 4,814 Bytes
27867f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
"""
MIT License

Copyright (C) 2021 ROCKY4546
https://github.com/rocky4546

This file is part of Cabernet

Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or
substantial portions of the Software.
"""

import logging

from lib.web.pages.templates import web_templates
from lib.clients.web_handler import WebHTTPHandler
import lib.common.utils as utils


class Stream:
    logger = None

    def __init__(self, _plugins, _hdhr_queue):
        self.plugins = _plugins
        self.namespace = ''
        self.instance = ''
        self.config = self.plugins.config_obj.data
        self.hdhr_queue = _hdhr_queue
        if Stream.logger is None:
            Stream.logger = logging.getLogger(__name__)

    def put_hdhr_queue(self, _namespace, _index, _channel, _status):
        if not self.config['hdhomerun']['disable_hdhr']:
            self.hdhr_queue.put(
                {'namespace': _namespace, 'tuner': _index,
                 'channel': _channel, 'status': _status})

    def find_tuner(self, _namespace, _instance, _ch_num, _isvod):
        # keep track of how many tuners we can use at a time
        found = -1
        scan_list = WebHTTPHandler.rmg_station_scans[_namespace]
        for index, scan_status in enumerate(scan_list):
            # the first idle tuner gets it
            if scan_status == 'Idle' and found == -1:
                found = index
            elif isinstance(scan_status, dict):
                if scan_status['instance'] == _instance \
                        and scan_status['ch'] == _ch_num \
                        and not _isvod \
                        and scan_status['mux'] \
                        and not scan_status['mux'].terminate_requested:
                    found = index
                    break
        if found == -1:
            return found
        if WebHTTPHandler.rmg_station_scans[_namespace][index] != 'Idle':
            self.logger.debug('Reusing tuner {} {}:{} ch:{}'.format(found, _namespace, _instance, _ch_num))
        else:
            self.logger.debug('Adding new tuner {} for stream {}:{} ch:{}'.format(found, _namespace, _instance, _ch_num))
            WebHTTPHandler.rmg_station_scans[_namespace][found] = { \
                'instance': _instance,
                'ch': _ch_num,
                'mux': None,
                'status': 'Starting'}
            self.put_hdhr_queue(_namespace, index, _ch_num, 'Stream')
        return found

    def set_service_name(self, _channel_dict):
        updated_chnum = utils.wrap_chnum(
            str(_channel_dict['display_number']), _channel_dict['namespace'],
            _channel_dict['instance'], self.config)

        if self.config['epg']['epg_channel_number']:
            service_name = updated_chnum + \
                           ' ' + _channel_dict['display_name']
        else:
            service_name = _channel_dict['display_name']
        return service_name

    def get_stream_uri(self, _channel_dict):
        return self.plugins.plugins[_channel_dict['namespace']] \
            .plugin_obj.get_channel_uri_ext(_channel_dict['uid'], _channel_dict['instance'])

    def gen_response(self, _namespace, _instance, _ch_num, _isvod):
        """
        Returns dict where the dict is consistent with
        the method do_dict_response requires as an argument
        A code other than 200 means do not tune
        dict also include a "tuner_index" that informs caller what tuner is allocated
        """
        self.namespace = _namespace
        self.instance = _instance
        i = self.find_tuner(_namespace, _instance, _ch_num, _isvod)
        if i >= 0:
            return {
                'tuner': i,
                'code': 200,
                'headers': {'Content-type': 'video/MP2T;'},
                'text': None}
        else:
            self.logger.warning(
                'All tuners already in use [{}][{}] max tuners: {}'
                .format(_namespace, _instance, len(WebHTTPHandler.rmg_station_scans[_namespace])))
            return {
                'tuner': i,
                'code': 400,
                'headers': {'Content-type': 'text/html'},
                'text': web_templates['htmlError'].format('400 - All tuners already in use.')}

    @property
    def config_section(self):
        return utils.instance_config_section(self.namespace, self.instance)