Skip to content

Commit

Permalink
fixed TV show aspect ratio detection
Browse files Browse the repository at this point in the history
  • Loading branch information
osumoclement committed Oct 8, 2023
1 parent 7bd7561 commit 3c076d7
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 50 deletions.
103 changes: 62 additions & 41 deletions addon.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
CaptureWidth = 48
CaptureHeight = 54


def notify(msg):
xbmcgui.Dialog().notification("BlackBarsNever", msg, None, 1000)

Expand All @@ -24,13 +25,13 @@ def __init__(self):
xbmc.Player.__init__(self)

if "toggle" in sys.argv:
if xbmcgui.Window(10000).getProperty('blackbarsnever_status') == "on":
if xbmcgui.Window(10000).getProperty("blackbarsnever_status") == "on":
self.showOriginal()
else:
self.abolishBlackBars()

def onAVStarted(self):
if (xbmcaddon.Addon().getSetting("automatically_execute") == "true"):
if xbmcaddon.Addon().getSetting("automatically_execute") == "true":
self.abolishBlackBars()
else:
self.showOriginal()
Expand All @@ -56,7 +57,7 @@ def LineColorLessThan(self, _bArray, _lineStart, _lineCount, _threshold):

# zero out the alpha channel
i = __sliceStart + 3
while (i < __sliceEnd):
while i < __sliceEnd:
_bArray[i] &= 0x00
i += 4

Expand All @@ -76,19 +77,18 @@ def GetAspectRatioFromFrame(self):
__aspect_ratio = int((capture.getAspectRatio() + 0.005) * 100)
__threshold = 25

line1 = 'Interim Aspect Ratio = ' + str(__aspect_ratio)
line1 = "Interim Aspect Ratio = " + str(__aspect_ratio)
xbmc.log(line1, level=xbmc.LOGINFO)

# screen capture and test for an image that is not dark in the 2.40
# aspect ratio area. keep on capturing images until captured image
# is not dark
while (True):
while True:
__myimage = self.CaptureFrame()

xbmc.log(line1, level=xbmc.LOGINFO)

__middleScreenDark = self.LineColorLessThan(
__myimage, 7, 2, __threshold)
__middleScreenDark = self.LineColorLessThan(__myimage, 7, 2, __threshold)
if __middleScreenDark == False:
# xbmc.sleep(1000)
break
Expand All @@ -102,41 +102,49 @@ def GetAspectRatioFromFrame(self):
__ar200 = self.LineColorLessThan(__myimage, 1, 3, __threshold)
__ar235 = self.LineColorLessThan(__myimage, 1, 5, __threshold)

if (__ar235 == True):
if __ar235 == True:
__aspect_ratio = 235

elif (__ar200 == True):
elif __ar200 == True:
__aspect_ratio = 200

elif (__ar185 == True):
elif __ar185 == True:
__aspect_ratio = 185

return __aspect_ratio

def abolishBlackBars(self):
xbmcgui.Window(10000).setProperty('blackbarsnever_status', "on")
xbmcgui.Window(10000).setProperty("blackbarsnever_status", "on")
# notify(xbmcgui.Window(10000).getProperty('blackbarsnever_status'))

original_aspect_ratio = None
android_workaround = (xbmcaddon.Addon().getSetting(
"android_workaround") == 'true')
android_workaround = (
xbmcaddon.Addon().getSetting("android_workaround") == "true"
)

imdb_number = xbmc.getInfoLabel("VideoPlayer.IMDBNumber")
title = player.getVideoInfoTag().getTitle()
if not title:
title = player.getVideoInfoTag().getOriginalTitle()
if not title:
title = os.path.basename(
player.getVideoInfoTag().getFilenameAndPath()).split('/')[-1].split(".", 1)[0]

original_aspect_ratio = getOriginalAspectRatio(
title, imdb_number=imdb_number)

if player.getVideoInfoTag().getMediaType() == "episode":
# media is a TV show
title = player.getVideoInfoTag().getTVShowTitle()
else:
# media is probably a film
title = player.getVideoInfoTag().getTitle()
if not title:
title = player.getVideoInfoTag().getOriginalTitle()
if not title:
title = (
os.path.basename(player.getVideoInfoTag().getFilenameAndPath())
.split("/")[-1]
.split(".", 1)[0]
)

original_aspect_ratio = getOriginalAspectRatio(title, imdb_number=imdb_number)

if isinstance(original_aspect_ratio, list):
# media has multiple aspect ratios, show unaltered and let user do manual intervention
notify("Multiple aspect ratios detected")
else:
if android_workaround and original_aspect_ratio:
if android_workaround and original_aspect_ratio:
aspect_ratio = int(original_aspect_ratio)

self.doStiaff(aspect_ratio)
Expand All @@ -149,14 +157,18 @@ def doStiaff(self, ratio):
aspect_ratio2 = int((capture.getAspectRatio() + 0.005) * 100)

window_id = xbmcgui.getCurrentWindowId()
line1 = 'Calculated Aspect Ratio = ' + \
str(aspect_ratio) + ' ' + \
'Player Aspect Ratio = ' + str(aspect_ratio2)
line1 = (
"Calculated Aspect Ratio = "
+ str(aspect_ratio)
+ " "
+ "Player Aspect Ratio = "
+ str(aspect_ratio2)
)

xbmc.log(line1, level=xbmc.LOGINFO)

if (aspect_ratio > 178):
zoom_amount = (aspect_ratio / 178)
if aspect_ratio > 178:
zoom_amount = aspect_ratio / 178
else:
zoom_amount = 1.0

Expand All @@ -166,26 +178,35 @@ def doStiaff(self, ratio):
if (aspect_ratio > 178) and (aspect_ratio2 == 178):
# this is 16:9 and has hard coded black bars
xbmc.executeJSONRPC(
'{"jsonrpc": "2.0", "method": "Player.SetViewMode", "params": {"viewmode": {"zoom": ' + str(zoom_amount) + ' }}, "id": 1}')
notify(
"Black Bars were detected. Zoomed {:0.2f}".format(zoom_amount))
elif (aspect_ratio > 178):
'{"jsonrpc": "2.0", "method": "Player.SetViewMode", "params": {"viewmode": {"zoom": '
+ str(zoom_amount)
+ ' }}, "id": 1}'
)
notify("Black Bars were detected. Zoomed {:0.2f}".format(zoom_amount))
elif aspect_ratio > 178:
# this is an aspect ratio wider than 16:9, no black bars, we assume a 16:9 (1.77:1) display
xbmc.executeJSONRPC(
'{"jsonrpc": "2.0", "method": "Player.SetViewMode", "params": {"viewmode": {"zoom": ' + str(zoom_amount) + ' }}, "id": 1}')
if (zoom_amount <= 1.02):
notify(
"Wide screen was detected. Slightly zoomed {:0.2f}".format(zoom_amount))
elif (zoom_amount > 1.02):
'{"jsonrpc": "2.0", "method": "Player.SetViewMode", "params": {"viewmode": {"zoom": '
+ str(zoom_amount)
+ ' }}, "id": 1}'
)
if zoom_amount <= 1.02:
notify(
"Wide screen was detected. Zoomed {: 0.2f}".format(zoom_amount))
"Wide screen was detected. Slightly zoomed {:0.2f}".format(
zoom_amount
)
)
elif zoom_amount > 1.02:
notify("Wide screen was detected. Zoomed {: 0.2f}".format(zoom_amount))

def showOriginal(self):
xbmcgui.Window(10000).setProperty('blackbarsnever_status', "off")
xbmcgui.Window(10000).setProperty("blackbarsnever_status", "off")
# notify(xbmcgui.Window(10000).getProperty('blackbarsnever_status'))

xbmc.executeJSONRPC(
'{"jsonrpc": "2.0", "method": "Player.SetViewMode", "params": {"viewmode": {"zoom": 1.0' + ' }}, "id": 1}')
'{"jsonrpc": "2.0", "method": "Player.SetViewMode", "params": {"viewmode": {"zoom": 1.0'
+ ' }}, "id": 1}'
)
notify("Showing original aspect ratio")


Expand Down
2 changes: 1 addition & 1 deletion addon.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<addon id="script.black.bars.never" name="BlackBarsNever" version="1.0.9" provider-name="Clement Osumo">
<addon id="script.black.bars.never" name="BlackBarsNever" version="1.0.10" provider-name="Clement Osumo">
<requires>
<import addon="xbmc.python" version="3.0.0"/>
<import addon="script.module.requests" version="2.20.0"/>
Expand Down
26 changes: 18 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,54 @@
# BlackBarsNever Kodi Addon - Remove black bars

# How it works

This is an addon that eliminates black bars on KODI, whether hardcoded or the video is just wide format

With addon installed and enabled, it will automatically analyze media on playback and determine
With addon installed and enabled, it will automatically analyze media on playback and determine
if there are any black bars. The addon will then zoom the media exactly enough to cover the display.

The picture will not be distorted in any way as the zoom is linear,
however, on most media, small parts on the left and right will be cut off. Luckily, everything that's
important tends to fall in the middle of the scene 99% of the time. The advantages of experiencing an
however, on most media, small parts on the left and right will be cut off. Luckily, everything that's
important tends to fall in the middle of the scene 99% of the time. The advantages of experiencing an
immersive picture that fills the periphery should be enough to overweigh the disdvantage of missing sides.

# Supported platforms
# Supported platforms

- [x] Linux
- [x] Windows
- [x] macOS and iOS
- [x] Android & Embedded Systems - with workaround method

# Android & Embedded Systems like *ELEC

# Android & Embedded Systems like \*ELEC

Currently, Kodi can't capture sreenshots in Android and Embedded Systems if hardware accelertion is enabled due to some technical limitations. This may change in future and when that happens the addon will work properly like in other platforms. For now there's two options:

1) Disable hardware acceleration (turn off MediaCodec Surface in Android). The problem with this is that Kodi will now use CPU for decoding and playback may be affected to the point of being unwatchable, especially for high bitrate media. Also in the devices I tested, HDR won't work on Android if hardware acceleration is turned on, I am not sure if this affects all of Android.
1. Disable hardware acceleration (turn off MediaCodec Surface in Android). The problem with this is that Kodi will now use CPU for decoding and playback may be affected to the point of being unwatchable, especially for high bitrate media. Also in the devices I tested, HDR won't work on Android if hardware acceleration is turned on, I am not sure if this affects all of Android.

2) Enable the Android & Embedded Systems Workaround from the addon settings. This feature requires an internet connection to fetch media metadata, and works best if your library adopts a decent naming pattern i.e `Title Year`. Also works properly only if media aspect ratio is unchanged from original (i.e has not been cropped from the original)
2. Enable the Android & Embedded Systems Workaround from the addon settings. This feature requires an internet connection to fetch media metadata, and works best if your library adopts a decent naming pattern i.e `Title Year`. Also works properly only if media aspect ratio is unchanged from original (i.e has not been cropped from the original)

# Installation

Download the zip file from [releases](https://github.com/osumoclement/script.black.bars.never/releases)

Launch Kodi >> Add-ons >> Get More >> Install from zip file

You might want to turn off Overscan if your display is a TV by going to settings-> Aspect Ratio -> Just Scan

Feel free to ask any questions, submit feature/bug reports

# Multiple Aspect Ratios in Media

For media with multiple aspect ratios, the addon will notify you of this, and will do nothing. In such cases, I recommend you watch the media as is, since if you change the aspect ratio manually, you may not know where in the media the ratio changes in order to adjust again.
This feature requires internet to work

# Customization

There are a few ways to customize the addon
By default, the addon automatically removes black bars. If you want to change this behavior, you can turn this off in the addon settings. You would then need to manually trigger the addon by manually calling it from elsewhere in Kodi (ie from a Skin) like this `RunScript(script.black.bars.never,toggle)`. You could even map this to a key for convenience

To check the addon status elsewhere from Kodi, use this `xbmcgui.Window(10000).getProperty('blackbarsnever_status')`. The result is either `on` or `off`

# License

BlackBarsNever is [GPLv3 licensed](https://github.com/osumoclement/script.black.bars.never/blob/main/LICENSE). You may use, distribute and copy it under the license terms.

0 comments on commit 3c076d7

Please sign in to comment.