mirror of
https://github.com/LCTT/TranslateProject.git
synced 2025-03-12 01:40:10 +08:00
Merge remote-tracking branch 'LCTT/master'
This commit is contained in:
commit
8086718753
@ -26,7 +26,7 @@ Pantheon 桌面整洁、吸引人,并且有许多用户希望在桌面中获
|
||||
|
||||
最明显的例子是“文件名高亮”。几十年来,Mac OS 一直有一个广受欢迎的功能,你可以高亮显示重要文件的名称。人们使用此功能作为快速视觉指示器,来告诉自己哪个文件是这几个的“最佳”版本,或者哪个文件应该发送给朋友,或者哪个文件仍然需要处理。它们可以是任意颜色,可以表示用户想要的任何含义。最重要的是,它是引人注目的视觉元数据。
|
||||
|
||||
从 Mac OS 切换过来用户往往会错过 GNOME 和 KDE 以及其他 Linux 桌面提供的这个功能。Pantheon 悄悄地随手解决了这个问题。
|
||||
从 Mac OS 切换过来用户往往会在 GNOME 和 KDE 以及 Linux 提供的其它桌面里怀念这个功能。Pantheon 悄悄地随手解决了这个问题。
|
||||
|
||||
![A highlighted file in the Pantheon desktop][5]
|
||||
|
||||
|
@ -0,0 +1,77 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (5G in 2020: Still just a private party)
|
||||
[#]: via: (https://www.networkworld.com/article/3488563/5g-in-2020-still-just-a-private-party.html)
|
||||
[#]: author: (Jon Gold https://www.networkworld.com/author/Jon-Gold/)
|
||||
|
||||
5G in 2020: Still just a private party
|
||||
======
|
||||
|
||||
Vertigo3D / Getty Images
|
||||
|
||||
To hear the major mobile carriers talk about it, [5G][1] is here. They’ve deployed it, it works, and it’s ready to start changing the world just about right away, with ultra-fast connectivity, low latency and a dramatically improved ability to handle huge numbers of different connections at once.
|
||||
|
||||
Eventually, that will all be true – but, according to experts in the field, it isn’t yet, and most of it won’t take place within the coming calendar year. The 3GPP standards that will underpin all new-radio 5G technology are still not yet finalized, although that is expected to happen in early 2020, which means the much-touted 5G deployments in the U.S. are based partially on pre-standard technology.
|
||||
|
||||
[[Get regularly scheduled insights by signing up for Network World newsletters.]][2]
|
||||
|
||||
Those deployments are also, at this point, quite limited in size, confined to a few major cities, and only covering centrally located intersections and occasional landmarks. It’s worth noting, though, that the parts of the 5G standard that work over some of the same frequencies as existing LTE have been finalized.
|
||||
|
||||
[][3]
|
||||
|
||||
BrandPost Sponsored by HPE
|
||||
|
||||
[Take the Intelligent Route with Consumption-Based Storage][3]
|
||||
|
||||
Combine the agility and economics of HPE storage with HPE GreenLake and run your IT department with efficiency.
|
||||
|
||||
Babak Beheshti, a member of the IEEE’s board of directors, said that the main way 5G will make a mark in 2020 will be in private deployments. A company can use pre-standard versions of 5G to create very fast, low-latency networks within its own facilities. Vendors like Ericsson and Nokia are already getting ready to sell the requisite equipment, and a private 5G network has a number of potential upsides, thanks in part to it being based on existing carrier technology.
|
||||
|
||||
“Because of its inherent privacy and security, in that sense, it’ll provide wireless access to employees at a much more secure level,” he said.
|
||||
|
||||
Beheshti also noted that there are potential downsides to the use of private 5G – including cost and the fact that it will require a fairly dense deployment of access points, given its use of comparatively high-frequency radio waves.
|
||||
|
||||
According to Forrester Research vice president Glenn O’Donnell, another potential issue is power consumption – compared to a [Wi-Fi 6][4] network of similar capacity, at least – but that’s an arguable point, and both technologies will be competitive for this type of deployment.
|
||||
|
||||
“This is one of the many holy wars we’ve seen in technology,” he said. “You’ll get people who fall into one camp or the other – a lot of it, unfortunately, is going to come down to who’s marketing better.”
|
||||
|
||||
Still, it seems clear that there’s a potential market there in the enterprise sector for a fast, low-latency network that’s also highly secure. O’Donnell said that the manufacturing, warehousing and logistics verticals might be particularly interested in private 5G, given the networking needs created by IoT and related developments and a lesser incidence of highly sophisticated Wi-Fi implementations.
|
||||
|
||||
Beheshti concurred, saying that a relatively green field makes the most sense for private 5G deployment.
|
||||
|
||||
“Given the expenditure involved, where it would really provide most ROI is for companies that have no private wireless or very little private wireless setup or infrastructure,” he said.
|
||||
|
||||
Widespread carrier-based implementation of 5G technology, however, is unlikely to happen over the course of 2020, and a big part of the reason why is that the devices on the market that are compatible with 5G networks are slim to non-existent.
|
||||
|
||||
According to O’Donnell, software-defined 5G radios are present on some of the latest Samsung phones and a few handsets made in China, and they’re likely capable of being reconfigured with OTA updates to mesh with any final standard for the millimeter-wave technology that provides 5G’s most impressive connection speeds. Yet that’s not a guarantee.
|
||||
|
||||
“If a new band opened up that nobody foresaw as a possibility, that could cause hiccups,” he said.
|
||||
|
||||
It’s easy to understand the reason behind all the hype. The mobile carriers are eager to tout their cutting-edge technology, and full-fledged 5G will be an undeniably impressive achievement. It will enable a huge range of new wireless applications, and improve overall connectivity for just about every user. But the fact remains that it’s not going to do all that in 2020, and, beyond the limited use case for private implementations of the technology, 5G isn’t something that enterprise users will need to concern themselves with too heavily in the coming year.
|
||||
|
||||
“I fully believe 5G is going to be transformative, but it needs to be built out,” said O’Donnell. “This is going to take time and a lot of money.”
|
||||
|
||||
Join the Network World communities on [Facebook][5] and [LinkedIn][6] to comment on topics that are top of mind.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://www.networkworld.com/article/3488563/5g-in-2020-still-just-a-private-party.html
|
||||
|
||||
作者:[Jon Gold][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://www.networkworld.com/author/Jon-Gold/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://www.networkworld.com/article/3203489/what-is-5g-how-is-it-better-than-4g.html
|
||||
[2]: https://www.networkworld.com/newsletters/signup.html
|
||||
[3]: https://www.networkworld.com/article/3440100/take-the-intelligent-route-with-consumption-based-storage.html?utm_source=IDG&utm_medium=promotions&utm_campaign=HPE20773&utm_content=sidebar ( Take the Intelligent Route with Consumption-Based Storage)
|
||||
[4]: https://www.networkworld.com/article/3356838/how-to-determine-if-wi-fi-6-is-right-for-you.html
|
||||
[5]: https://www.facebook.com/NetworkWorld/
|
||||
[6]: https://www.linkedin.com/company/network-world
|
200
sources/tech/20191208 Dynamically scoped variables in Go.md
Normal file
200
sources/tech/20191208 Dynamically scoped variables in Go.md
Normal file
@ -0,0 +1,200 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (Dynamically scoped variables in Go)
|
||||
[#]: via: (https://dave.cheney.net/2019/12/08/dynamically-scoped-variables-in-go)
|
||||
[#]: author: (Dave Cheney https://dave.cheney.net/author/davecheney)
|
||||
|
||||
Dynamically scoped variables in Go
|
||||
======
|
||||
|
||||
This is a thought experiment in API design. It starts with the classic Go unit testing idiom:
|
||||
|
||||
```
|
||||
func TestOpenFile(t *testing.T) {
|
||||
f, err := os.Open("notfound")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
What’s the problem with this code? The assertion. `if err != nil { ... }` is repetitive and in the case where multiple conditions need to be checked, somewhat error prone if the author of the test uses `t.Error` not `t.Fatal`, eg:
|
||||
|
||||
```
|
||||
f, err := os.Open("notfound")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
f.Close() // boom!
|
||||
```
|
||||
|
||||
What’s the solution? DRY it up, of course, by moving the repetitive assertion logic to a helper:
|
||||
|
||||
```
|
||||
func TestOpenFile(t *testing.T) {
|
||||
f, err := os.Open("notfound")
|
||||
check(t, err)
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
func check(t *testing.T, err error) {
|
||||
if err != nil {
|
||||
t.Helper()
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Using the `check` helper the code is a little cleaner, and clearer, _check the error_, and hopefully the indecision between `t.Error` and `t.Fatal` has been solved. The downside of abstracting the assertion to a helper function is now you need to pass a `testing.T` into _each and every invocation_. Worse, you need to pass a `*testing.T` to everything that needs to call `check`, transitively, just in case.
|
||||
|
||||
This is ok, I guess, but I will make the observation that the `t` variable is only needed _when the assertion fails_ — and even in a testing scenario, most of the time, most of the tests pass, so that means reading, and writing, all these `t`‘s is a constant overhead for the relatively rare occasion that a test fails.
|
||||
|
||||
What about if we did something like this instead?
|
||||
|
||||
```
|
||||
func TestOpenFile(t *testing.T) {
|
||||
f, err := os.Open("notfound")
|
||||
check(err)
|
||||
|
||||
// ...
|
||||
}
|
||||
|
||||
func check(err error) {
|
||||
if err != nil {
|
||||
panic(err.Error())
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Yeah, that’ll work, but it has a few problems
|
||||
|
||||
```
|
||||
% go test
|
||||
--- FAIL: TestOpenFile (0.00s)
|
||||
panic: open notfound: no such file or directory [recovered]
|
||||
panic: open notfound: no such file or directory
|
||||
|
||||
goroutine 22 [running]:
|
||||
testing.tRunner.func1(0xc0000b4400)
|
||||
/Users/dfc/go/src/testing/testing.go:874 +0x3a3
|
||||
panic(0x111b040, 0xc0000866f0)
|
||||
/Users/dfc/go/src/runtime/panic.go:679 +0x1b2
|
||||
github.com/pkg/expect_test.check(...)
|
||||
/Users/dfc/src/github.com/pkg/expect/expect_test.go:18
|
||||
github.com/pkg/expect_test.TestOpenFile(0xc0000b4400)
|
||||
/Users/dfc/src/github.com/pkg/expect/expect_test.go:10 +0xa1
|
||||
testing.tRunner(0xc0000b4400, 0x115ac90)
|
||||
/Users/dfc/go/src/testing/testing.go:909 +0xc9
|
||||
created by testing.(*T).Run
|
||||
/Users/dfc/go/src/testing/testing.go:960 +0x350
|
||||
exit status 2
|
||||
```
|
||||
|
||||
Let’s start with the good; we didn’t have to pass a `testing.T` every place we call `check`, the test fails immediately, and we get a nice message in the panic — albeit twice. But _where_ the assertion failed is hard to see. It occurred on `expect_test.go:11` but you’d be forgiven for not knowing that.
|
||||
|
||||
So `panic` isn’t really a good solution, but there’s something in this stack trace that is — can you see it? Here’s a hint, `github.com/pkg/expect_test.TestOpenFile(0xc0000b4400)`.
|
||||
|
||||
`TestOpenFile` has a `t` value, it was passed to it by `tRunner`, so there’s a `testing.T` in memory at address `0xc0000b4400`. What if we could get access to that `t` inside `check`? Then we could use it to call `t.Helper` and `t.Fatal`. Is that possible?
|
||||
|
||||
### Dynamic scoping
|
||||
|
||||
What we want is to be able to access a variable whose declaration is neither global, or local to the function, but somewhere higher in the call stack. This is called _dynamic scoping_. Go doesn’t support dynamic scoping, but it turns out, for restricted cases, we can fake it. I’ll skip to the chase:
|
||||
|
||||
```
|
||||
// getT returns the address of the testing.T passed to testing.tRunner
|
||||
// which called the function which called getT. If testing.tRunner cannot
|
||||
// be located in the stack, say if getT is not called from the main test
|
||||
// goroutine, getT returns nil.
|
||||
func getT() *testing.T {
|
||||
var buf [8192]byte
|
||||
n := runtime.Stack(buf[:], false)
|
||||
sc := bufio.NewScanner(bytes.NewReader(buf[:n]))
|
||||
for sc.Scan() {
|
||||
var p uintptr
|
||||
n, _ := fmt.Sscanf(sc.Text(), "testing.tRunner(%v", &p)
|
||||
if n != 1 {
|
||||
continue
|
||||
}
|
||||
return (*testing.T)(unsafe.Pointer(p))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
We know that each `Test` is called by the `testing` package in its own goroutine (see the stack trace above). The `testing` package launches the test via a function called `tRunner` which takes a `*testing.T` and a `func(*testing.T)` to invoke. Thus we grab a stack trace of the current goroutine, scan through it for the line beginning with `testing.tRunner` — which can only be the `testing` package as `tRunner` is a private function — and parse the address of the first parameter, which is a pointer to a `testing.T`. With a little `unsafe` we convert the raw pointer back to a `*testing.T` and we’re done.
|
||||
|
||||
If the search fails then it is likely that `getT` wasn’t called from a `Test`. This is actually ok because the reason we needed the `*testing.T` was to call `t.Fatal` and the testing package already requires that `t.Fatal` be called from the [main test goroutine][1].
|
||||
|
||||
```
|
||||
import "github.com/pkg/expect"
|
||||
|
||||
func TestOpenFile(t *testing.T) {
|
||||
f, err := os.Open("notfound")
|
||||
expect.Nil(err)
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Putting it all together we’ve eliminated the assertion boilerplate and possibly made the expectation of the test a little clearer to read, _after opening the file `err` is expected to be nil_.
|
||||
|
||||
### Is this fine?
|
||||
|
||||
At this point you should be asking, _is this fine?_ And the answer is, no, this is not fine. You should be screaming internally at this point. But it’s probably worth introspecting those feelings of revulsion.
|
||||
|
||||
Apart from the inherent fragility of scrobbling around in a goroutine’s call stack, there are some serious design issues:
|
||||
|
||||
1. The `expect.Nil`‘s behaviour now depends on _who called it_. Provided with the same arguments it may have different behaviour depending on where it appears in the call stack — this is unexpected.
|
||||
2. Taken to the extreme dynamic scoping effective brings into the scope of a single function all the variables passed into any function that preceded it. It is a side channel for passing data in to and out of functions that is not explicitly documented in function declaration.
|
||||
|
||||
|
||||
|
||||
Ironically these are precisely the critiques I have of [`context.Context`][2]. I’ll leave it to you to decide if they are justified.
|
||||
|
||||
### A final word
|
||||
|
||||
This is a bad idea, no argument there. This is not a pattern you should ever use in production code. But, this isn’t production code, it’s a test, and perhaps there are different rules that apply to test code. After all, we use mocks, and stubs, and monkey patching, and type assertions, and reflection, and helper functions, and build flags, and global variables, all so we can test our code effectively. None of those, uh, _hacks_ will ever show up in the production code path, so is it really the end of the world?
|
||||
|
||||
If you’ve read this far perhaps you’ll agree with me that as unconventional as this approach is, not having to pass a `*testing.T` into every function that could possibly need to assert something transitively, makes for clearer test code.
|
||||
|
||||
So maybe, in this case, the ends do justify the means.
|
||||
|
||||
* * *
|
||||
|
||||
If you’re interested, I’ve put together a [small assertion library][3] using this pattern. _Caveat emptor_.
|
||||
|
||||
#### Related posts:
|
||||
|
||||
1. [Go, without package scoped variables][4]
|
||||
2. [On declaring variables][5]
|
||||
3. [A whirlwind tour of Go’s runtime environment variables][6]
|
||||
4. [You shouldn’t name your variables after their types for the same reason you wouldn’t name your pets “dog” or “cat”][7]
|
||||
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://dave.cheney.net/2019/12/08/dynamically-scoped-variables-in-go
|
||||
|
||||
作者:[Dave Cheney][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://dave.cheney.net/author/davecheney
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://golang.org/pkg/testing/#T.FailNow
|
||||
[2]: https://dave.cheney.net/2017/01/26/context-is-for-cancelation
|
||||
[3]: https://github.com/pkg/expect
|
||||
[4]: https://dave.cheney.net/2017/06/11/go-without-package-scoped-variables (Go, without package scoped variables)
|
||||
[5]: https://dave.cheney.net/2014/05/24/on-declaring-variables (On declaring variables)
|
||||
[6]: https://dave.cheney.net/2015/11/29/a-whirlwind-tour-of-gos-runtime-environment-variables (A whirlwind tour of Go’s runtime environment variables)
|
||||
[7]: https://dave.cheney.net/2019/01/29/you-shouldnt-name-your-variables-after-their-types-for-the-same-reason-you-wouldnt-name-your-pets-dog-or-cat (You shouldn’t name your variables after their types for the same reason you wouldn’t name your pets “dog” or “cat”)
|
@ -0,0 +1,151 @@
|
||||
[#]: collector: (lujun9972)
|
||||
[#]: translator: ( )
|
||||
[#]: reviewer: ( )
|
||||
[#]: publisher: ( )
|
||||
[#]: url: ( )
|
||||
[#]: subject: (App Highlight: Open Source Video Transcoder Handbrake)
|
||||
[#]: via: (https://itsfoss.com/handbrake/)
|
||||
[#]: author: (Ankush Das https://itsfoss.com/author/ankush/)
|
||||
|
||||
App Highlight: Open Source Video Transcoder Handbrake
|
||||
======
|
||||
|
||||
_**Brief: HandBrake is a free and open-source video conversion tool that is quite useful. Let’s see what are its main features and how to use them for converting videos from one format to another.**_
|
||||
|
||||
### HandBrake: An Open Source Video Transcoder
|
||||
|
||||
![][1]
|
||||
|
||||
[HandBrake][2] is a quite useful tool which helps you to convert a video from one format to some of the widely supported codecs (**.mp4/.m4v/.mkv/.webm**)
|
||||
|
||||
It can support any video format and help you convert it. In addition to that, you have several features on board to customize the video attributes while converting.
|
||||
|
||||
If you are looking for a [Format Factory alternative][3], this is your best bet.
|
||||
|
||||
I shall highlight the key features to help you know more.
|
||||
|
||||
![HandBrake][4]
|
||||
|
||||
### Features of HandBrake
|
||||
|
||||
When you start using the video transcoder, you will find a lot of tiny features for video conversion. However, here, I’ll highlight the important things you need to know about HandBrake:
|
||||
|
||||
#### Video Conversion Presets
|
||||
|
||||
![HandBrake Presets][5]
|
||||
|
||||
Suppose you want to convert a full HD video to play on a mobile which was originally tailored for desktop viewing, what do you do?
|
||||
|
||||
Would you test various dimensions and convert them repeatedly to get the perfect mobile port? Or, would you rather prefer to have pre-defined settings for such conversions?
|
||||
|
||||
If you opt for a preset, you just have to select the target device (or type of device) from the list of available presets.
|
||||
|
||||
It even features presets for PS4 Pro (4K) and Discord. So, you can expect a big list of presets available.
|
||||
|
||||
#### Input Sources Support
|
||||
|
||||
Unless the file has some sort of copy protection, HandBrake can help you convert it. You will have no problems whatsoever even if you have an Ultra HD Blu-ray disc as the source with no copyright protection.
|
||||
|
||||
All the available video encoding formats should work fine as an input source file.
|
||||
|
||||
#### Basic Video Manipulation
|
||||
|
||||
![HandBrake Screenshot][6]
|
||||
|
||||
In addition to the ability of video conversion, it also lets you tweak the video to suit your requirements.
|
||||
|
||||
You can change the dimensions, crop it, add a filter, change the frame rate settings, and a lot more things.
|
||||
|
||||
If that wasn’t enough, you also get the ability to add subtitles and chapter markers.
|
||||
|
||||
#### Live Video Preview
|
||||
|
||||
This may not be a big deal to have – but I haven’t seen any video converter tool featuring video previews while being able to convert/tweak the video. It could come in handy for someone specific.
|
||||
|
||||
### Installing HandBrake on Ubuntu and other Linux distributions
|
||||
|
||||
HandBrake is a cross-platform application and you can install it on all different platforms like Linux, macOS and Windows. Just head over to heir website and download it from there.
|
||||
|
||||
[Download HandBrake for any platform][7]
|
||||
|
||||
On It’s FOSS, our focus is on Linux so I am going to show the steps to install it on Linux.
|
||||
|
||||
**Installing HandBrake on Ubuntu**
|
||||
|
||||
HandBrake is available in the [universe repository in Ubuntu][8]. If you have it enabled, you should find it in the software center. Just search for the name and install it from there.
|
||||
|
||||
![HandBrake in Ubuntu Software Center][9]
|
||||
|
||||
You can also use terminal for installing HandBrake with apt or [apt-get command][10]:
|
||||
|
||||
```
|
||||
sudo apt-get install handbrake
|
||||
```
|
||||
|
||||
However, the software center might feature the older version. If you want to install the latest version of HandBrake on Ubuntu and other Ubuntu-based distributions, you can [use its official PPA][11]. It’s better to uninstall any existing version of HandBrake beforehand.
|
||||
|
||||
```
|
||||
sudo apt remove handbrake
|
||||
sudo add-apt-repository ppa:stebbins/handbrake-releases
|
||||
sudo apt update
|
||||
sudo apt install handbrake-gtk
|
||||
```
|
||||
|
||||
You can [learn more about using PPA here][12]. It will help you to [remove PPA][13], if you ever need to uninstall HandBrake installed via the PPA.
|
||||
|
||||
If you want to install the CLI version of Handbrake, simply use this command:
|
||||
|
||||
```
|
||||
sudo apt install handbrake-cli
|
||||
```
|
||||
|
||||
Quite honestly, HandBrake should be used as a GUI application. If you want command line, you can always [use ffmpeg][14] that is more powerful and HandBrake uses it underneath anyways.
|
||||
|
||||
**Installing HandBrake on other Linux distributions**
|
||||
|
||||
HandBrake is one of the [popular Linux software][15] and it should be available in the official repositories of almost all Linux distributions.
|
||||
|
||||
Just use the software center or package manager of your distribution to install HandBrake.
|
||||
|
||||
But again, your distribution might not have the latest version of HandBrale. So, if you want the latest version installed, you can try installing the [Flatpak package][16] available. If you are not sure how to use Flatpak, refer to our guide on [using Flatpak on Linux][17].
|
||||
|
||||
[HandBrake][2]
|
||||
|
||||
**Wrapping Up**
|
||||
|
||||
A free and open-source video conversion tool that gets the job done. I’m quite satisfied with it personally.
|
||||
|
||||
If you use HandBrake extensively, mention at least one feature that you like the most about it.
|
||||
|
||||
If you use some other application for converting video formats, do share it with us in the comments.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
via: https://itsfoss.com/handbrake/
|
||||
|
||||
作者:[Ankush Das][a]
|
||||
选题:[lujun9972][b]
|
||||
译者:[译者ID](https://github.com/译者ID)
|
||||
校对:[校对者ID](https://github.com/校对者ID)
|
||||
|
||||
本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出
|
||||
|
||||
[a]: https://itsfoss.com/author/ankush/
|
||||
[b]: https://github.com/lujun9972
|
||||
[1]: https://i2.wp.com/itsfoss.com/wp-content/uploads/2019/12/handbrake_software_logo.png?ssl=1
|
||||
[2]: https://handbrake.fr/
|
||||
[3]: https://itsfoss.com/format-factory-alternative-linux/
|
||||
[4]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/11/handbrake.png?ssl=1
|
||||
[5]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/11/handbrake-presets.png?ssl=1
|
||||
[6]: https://i0.wp.com/itsfoss.com/wp-content/uploads/2019/11/handbrake-screenshot.png?ssl=1
|
||||
[7]: https://handbrake.fr/downloads.php
|
||||
[8]: https://itsfoss.com/ubuntu-repositories/
|
||||
[9]: https://i1.wp.com/itsfoss.com/wp-content/uploads/2019/11/handbrake_ubuntu_software_center.png?ssl=1
|
||||
[10]: https://itsfoss.com/apt-get-linux-guide/
|
||||
[11]: https://launchpad.net/~stebbins/+archive/ubuntu/handbrake-releases
|
||||
[12]: https://itsfoss.com/ppa-guide/
|
||||
[13]: https://itsfoss.com/how-to-remove-or-delete-ppas-quick-tip/
|
||||
[14]: https://itsfoss.com/ffmpeg/
|
||||
[15]: https://itsfoss.com/essential-linux-applications/
|
||||
[16]: https://flathub.org/apps/details/fr.handbrake.ghb
|
||||
[17]: https://itsfoss.com/flatpak-guide/
|
Loading…
Reference in New Issue
Block a user